判断ccss≠0替代sqrt(ccss)≠0,浮点运算下是否安全?
关于两段C语言代码的安全性疑问
问题背景
用户提供了两段C语言代码,想确认第二段写法是否安全:
第一段代码
double ccss = c * c + s * s; double sqrtCCSS = sqrt(ccss); if (sqrtCCSS != 0) { n = n1 / sqrtCCSS; }
第二段代码
double ccss = c * c + s * s; if (ccss != 0) { n = n1 / sqrt(ccss); }
核心疑问
当x>0时,sqrt(x)是否可能因浮点误差返回0值?用户在Python的numpy中测试最小正浮点数,发现其平方根仍为非0值,疑惑是否存在特殊浮点误差场景导致该问题。
解答
第二段写法是完全安全的,理由如下:
- 目前绝大多数系统的浮点数实现都遵循IEEE 754标准,在这个标准下,只要
x是正的有限浮点数,sqrt(x)的结果一定是正的有限浮点数,绝不可能返回0。 - 就算是
double类型里最小的正数值(比如DBL_MIN),它的平方根依然是一个正的非0浮点数——系统会用当前精度能表示的最小正平方根来存储它,不会出现下溢到0的情况。 - 哪怕
ccss是个极小的正数值,sqrt(ccss)的结果也只会是对应精度下的极小正数,而非0。而ccss是两个数的平方和,不可能为负,所以只要ccss != 0,就说明它是正数,此时sqrt(ccss)必然非0,不会触发除以0的错误。
内容的提问来源于stack exchange,提问作者mas
相关产品推荐
相关产品推荐

