必须包含头文件并使用std::sqrt;支持多类型重载,负数返回NaN,大整数开方需防浮点误差,推荐整数二分或验证r*r==n。

sqrt 函数必须包含 头文件
直接写 sqrt(4.0) 会编译失败,错误通常是 ‘sqrt’ was not declared in this scope。C++ 标准库把数学函数放在 (不是 ),且不自动引入全局命名空间。
正确做法是:
#include#include int main() { double x = 16.0; std::cout << std::sqrt(x) << "\n"; // 推荐显式用 std::sqrt return 0; }
-
std::sqrt是标准写法;用using namespace std;虽能省略std::,但易引发命名冲突,不推荐 -
中的sqrt有多个重载:支持float、double、long double,传入整数(如int)会隐式转为double,但结果仍是double - 传入负数(如
sqrt(-1.0))在大多数平台返回NaN,不会抛异常,也不报错——需手动检查输入
整数平方根要小心类型和精度问题
如果目标是求整数 n 的“向下取整平方根”(比如 sqrt(10) → 3),不能只靠 static_cast,因为浮点计算可能有舍入误差。
例如:std::sqrt(25) + 1e-15 可能被截断为 5,也可能因浮点误差变成 5.000000000000001,再转 int 还是 5;但对大整数(如接近 LLONG_MAX 的完全平方数),误差可能让结果偏小 1。
立即学习“C++免费学习笔记(深入)”;
- 安全做法:先转
double计算,再向零取整后微调 - 更可靠的是用整数二分法(尤其当
n是long long且不能转double精确表示时) - 若只是判断是否为完全平方数,可计算
r = static_cast,再验证(std::sqrt(n)); r*r == n || (r+1)*(r+1) == n
替代方案:std::sqrt 不是唯一选择
某些场景下 std::sqrt 并非最优。比如在嵌入式或性能敏感代码中,编译器可能无法内联或优化掉函数调用开销;或者需要处理向量数据。
- 启用编译器优化(如
-O2)后,std::sqrt通常会被内联并映射到 CPU 的sqrtss/sqrtsd指令,效率很高 - 若需批量计算,考虑用 SIMD(如 Intel SSE/AVX 的
_mm_sqrt_ps),但需手动向量化,且丧失可移植性 - C++20 引入了
和std::numbers::sqrt2等常量,但没提供新 sqrt 实现;仍依赖 - 自定义牛顿迭代仅在特殊需求(如固定点、无浮点单元)下才值得做,日常开发没必要
常见错误:混用 C 风格头文件或忽略返回值类型
错误写法包括:#include (C 头文件,不保证 std:: 命名空间)、int y = sqrt(9);(未声明、未包含、未指定命名空间)、sqrt(9.0f) 返回 double 却赋给 float 变量导致隐式降精度。
- 始终用
#include,而非 - 避免裸调用
sqrt;明确写std::sqrt - 注意返回值类型:传
float得float,传double得double,传long double得long double;不要假设都是double - 调试时可用
std::isnan()或std::isfinite()检查结果是否有效










