当输入为完全平方整数时,std::sqrtf的计算结果是否精确?
关于std::sqrtf处理完全平方数整数的精度问题
当输入的整数value是完全平方数时,用std::sqrtf计算后转int不一定能得到精确结果,核心原因是单精度浮点数(float)的精度有限:
float的有效尾数为24位(含隐含的1位),只能精确表示0到2²⁴-1(即0到16777215)之间的所有整数。在这个范围内:- 任何完全平方数都能被
float精确存储; std::sqrtf计算该值的平方根时,结果也是精确的float值;- 转成
int后能得到正确的整数根,此时你的代码是安全的。
- 任何完全平方数都能被
当
value超过2²⁴时,并非所有整数都能被float精确表示。比如4097²=16785409,这个数超出了float的精确整数范围,会被float近似为最近的可表示值。此时std::sqrtf计算这个近似值的平方根,结果不会精确等于4097,转成int后就会得到错误的根。
针对你的需求(对非完全平方数截断,对完全平方数精确获取根),更安全的做法是改用双精度的std::sqrt:
int root = static_cast<int>(std::sqrt(static_cast<double>(value)));
因为double的有效尾数有53位,能精确表示所有32位整数(最大值为2³¹-1,远小于2⁵³),所以对于任意32位整数范围内的完全平方数,std::sqrt都能返回精确的平方根,转int后结果正确。
内容的提问来源于stack exchange,提问作者M.kazem Akhgary
相关产品推荐
相关产品推荐

