sqrt函数需包含头文件,否则编译报错;支持float/double/long double重载,整数会隐式转double,负数返回NaN;无整数开方专用版本,边界值强转易出错,推荐校正法;C++20起支持constexpr浮点开方。

sqrt 函数必须包含 头文件
不加这行,编译器会报 undefined reference to sqrt 或 'sqrt' was not declared in this scope。C++ 标准库把数学函数全收在 里,不是 (那是 C 的头文件,虽部分编译器兼容但行为不可靠)。
常见错误:用 using namespace std; 后仍报错——问题不在命名空间,而在没包含头文件。
正确写法:
#include#include int main() { double x = 16.0; std::cout << std::sqrt(x) << "\n"; // 输出 4 }
sqrt 的重载版本只支持 float、double、long double
传整数(如 int、long long)进去不会报错,但会隐式转成 double 调用;可一旦传负数,结果就是 NaN(非数),且不抛异常。
立即学习“C++免费学习笔记(深入)”;
-
sqrt(-4)→ 返回NaN,输出可能显示为-nan或nan -
sqrt(25LL)→ 自动转为double,结果正确,但注意精度损失(long long超过 2⁵³ 后无法精确表示) - 没有
sqrt(int)专属重载,所以别指望它对整数做整数开方(比如返回int类型的 4 而非 4.0)
需要整数平方根?别直接用 sqrt 强转
写 (int)sqrt(n) 看似简单,但在边界值上极易出错。例如 n = 2147395600(= 46340²),某些平台下 sqrt 返回略小于 46340.0 的值,强转后变成 46339。
更可靠的做法是用二分查找或 std::sqrt 后手动校正:
long long isqrt(long long n) {
if (n < 0) return -1;
long long r = std::sqrt(n);
while (r * r > n) r--;
while ((r + 1) * (r + 1) <= n) r++;
return r;
}注意:该函数适用于 n ≤ 2⁶³−1,但乘法 r * r 可能溢出,生产环境建议用 n / r >= r 替代 r * r 判断。
性能与 constexpr 支持:C++20 起 std::sqrt 是 constexpr
在编译期能确定值时(如字面量、consteval 上下文),C++20 允许 std::sqrt(4.0) 直接算出 2.0 —— 但仅限浮点类型,且输入不能是负数(否则编译失败)。
典型误用:
-
constexpr double x = std::sqrt(-1.0);→ 编译错误,不是运行时NaN -
constexpr int n = 25; constexpr double s = std::sqrt(n);→ 合法,n隐式转double后参与常量求值
老标准(C++17 及以前)中 sqrt 不是 constexpr,若需编译期整数开方,只能手写 constexpr 二分或查表。
实际用 sqrt 时最易忽略的是负输入静默返回 NaN,而不是报错或抛异常;调试时看到输出是 nan 却没检查源数据是否为负,会浪费大量时间。









