Python浮点数求和精度疑问:为何大小相近的数相加结果更准?
浮点数不同求和顺序的精度差异原理
浮点数底层存储规则
Python 中的浮点数遵循 IEEE 754 双精度存储标准,每个浮点数由符号位、指数位、尾数位三部分组成,其中尾数位长度固定为52位,换算为十进制约为15~17位有效数字,超出有效数字范围的低位数值会被直接截断丢弃。
跨量级浮点数相加的精度丢失逻辑
当两个数的量级差距过大时,小数的有效数字会完全落在大数的有效数字覆盖范围之外,相加后小数的贡献会被直接截断,相当于小数部分没有参与计算。
举个简化的十进制模拟例子:假设我们的浮点数仅支持保留4位十进制有效数字:
- 大数为 100.0(表示为
1.000×10²) - 小数为 0.0001(表示为
1.000×10⁻⁴)
二者理论相加结果为 100.0001,但受限于有效数字长度,最终结果会被截断为1.000×10²即100.0,小数的部分完全丢失。
两种求和顺序的精度对比
- A顺序(从小到大累加):每次参与相加的两个数量级接近,累加总和缓慢增长,和下一个待加数值的量级差距始终很小,相加时低位有效数字不会被完全截断,累计精度损失更低。
- B顺序(从大到小累加):当总和累积到较大值后,后续待加的0.01、0.02等小数值和总和的量级差距越来越大,大量低位小数部分会被直接截断,累计精度损失远高于A顺序。
你可以用以下Python代码直观验证误差差异:
import math # 生成0.01到1.00的序列 num_list = [i * 0.01 for i in range(1, 101)] # 高精度求和作为基准值 exact_val = math.fsum(num_list) # 从小到大求和 sum_small_to_big = sum(num_list) # 从大到小求和 sum_big_to_small = sum(reversed(num_list)) print(f"基准精确值:{exact_val}") print(f"A顺序绝对误差:{abs(sum_small_to_big - exact_val)}") print(f"B顺序绝对误差:{abs(sum_big_to_small - exact_val)}")
运行后可观测到B顺序的误差明显大于A顺序。
内容的提问来源于stack exchange,提问作者KishuInu
相关产品推荐
相关产品推荐

