两个numpy.float64数值相加得到非预期结果如何解决
异常结果产生原因
这不是运算溢出,是双精度浮点数(float64)的正常精度特性:
- float64的有效十进制位数为15~17位,你用到的两个数值
1.4617937201411304和-1.4617937201411302,从第17位小数开始存在差异,两者实际差值为2e-16,和float64的机器精度(约2.22e-16,即float64能表示的最小相对误差)处于同一量级。 - 两个绝对值接近、符号相反的数相加时会出现灾难性抵消,原本的微小误差会被直接暴露出来,你得到的
1.1102230246251565e-16本质就是接近0的合理结果,并非计算错误。 - 你测试的
(a*2)/2运算没有涉及不同数值的抵消操作,仅对单个数做乘除,误差没有被放大,因此结果符合预期。
这类问题的解决方法
- 若误差量级远小于业务可接受范围,直接忽略即可,仅需要注意后续判断数值是否为0时,不要用
c == 0的严格相等判断,改用numpy提供的浮点近似相等接口:np.isclose(c, 0),或是自定义误差阈值abs(c) < 1e-12来做判断。 - 若需要更高的计算精度,可以在计算均值时就指定更高精度的数值类型,比如
np.float128(部分平台可能不支持),降低计算过程中的累积误差。 - 优化计算逻辑避免灾难性抵消场景,比如你当前计算两个数组均值的平均值的场景,可以直接合并两个数组后再求均值,从根源上避免两个接近值的抵消操作:
c = np.concatenate([arr1, arr2]).mean()
内容的提问来源于stack exchange,提问作者Link
相关产品推荐
相关产品推荐

