sqrt要求非负输入,负数返回NaN且可能静默失败;需链接-libm;优先用sqrt/sqrtf而非手写;long double精度跨平台不一致。
用
计算平方根,但必须传入非负数
直接调用
是最常用做法,但它对负数输入不定义——在大多数平台上会返回
(Not a Number),且可能触发浮点异常(取决于编译器和运行时设置)。这不是“报错”,而是静默出错,容易被忽略。
正数和零:安全,返回精确到浮点精度的平方根值
负数:返回
,
为 true;若开启 FPE 检查(如 GCC 的
或某些调试环境),可能中断执行
类型要匹配:
调用的是
,整数会被隐式转成
;想用
版本得写
,否则多一次类型转换
和
的实际差异不只是精度
这三个函数分别对应
、
、
输入/输出。区别不止是“算得更准”,还涉及性能和 ABI 兼容性。
通常比
快,尤其在向量化场景下(如启用
)
在 x86-64 Linux 上多数实现仍是软件模拟,慢很多;Windows MSVC 下甚至可能退化为
精度
跨平台时别假设
一定是 80-bit:Clang/LLVM 默认用 IEEE-754 binary64(即等同
)
编译时没链接
会导致
这是 Linux/macOS 上高频链接错误。C++ 标准库头文件
声明了
,但实现体在数学库
中,而 C++ 链接器默认不自动拉它。
C知道
CSDN推出的一款AI技术问答工具
下载
g++/clang++ 编译时需显式加
:例如
CMake 用户注意:
必须写,不能只靠
之类掩盖
Windows MSVC 一般无此问题(数学函数内建于 libcmt),但 MinGW-w64 同样要
替代方案:手写牛顿迭代或查表法只在极端场景有用
除非你在做嵌入式裸机、GPU shader、或对某段热代码做极致优化,否则不要自己实现平方根。现代
指令(x86 的
/
)已高度优化,且编译器能自动向量化循环中的多次调用。
立即学习
“
C++免费学习笔记(深入)
”;
牛顿法写出来容易,但收敛性、初值选择、边界处理(比如 0、极小值)全是坑
查表法内存占用大,缓存不友好,且插值误差难控
唯一常见例外:需要整数平方根(如判断是否为完全平方数),这时用
再平方验证,比纯整数二分略快但可读性差
事情说清了就结束。真正容易被忽略的是:负数输入不报错、链接漏
、以及误以为
在所有平台都提供扩展精度。
sqrtsqrtnannanstd::isnan(sqrt(-1))-ftrapvsqrt(4)double sqrt(double)doublefloatsqrtf(4.0f)sqrtfsqrtlfloatdoublelong doublesqrtfsqrt-march=native -ffast-mathsqrtldoublelong doubledoublelibmundefined reference to sqrtsqrtlibm-lmg++ main.cpp -lmtarget_link_libraries(myapp m)find_package(Threads)-lmsqrtsqrtsssqrtsdstatic_cast(std::round(sqrt(n))) -lmlong double