当两个浮点数大小相差过大时,较小的浮点数右移太多位导致有效位全部丢失,比如:
>>> 10**15+1.0
1000000000000001.0
>>> 10**16+1.0
1e+16 # 浮点数1.0完全丢失,没加上
>>> 0.3+0.6
0.8999999999999999 # 精度产生损失
常见场景为累加求和,和越来越大,达到能使有效位全部丢失的大小时,加法失效
补偿求和法
原理为将损失的精度记录下来,在下次做加法时加给较小的数
sum = 0
delta= 0.1
loss = 0
for i in range(10**10):
last_sum = sum
sum += delta + loss
# 损失 = 期望sum - 实际sum
# loss = last_sum + delta - sum, 这里last_sum + delta有精度损失,所以做下交换
# loss = last_sum - sum + delta
loss = last_sum - sum + delta