float累加出现 "大数吃小数" 造成精度错误,使用 Kahan Summation Algorithm 解决

 

假定 sum 是 value 累加n次的和,理论上来说,执行n次 sum += value  后, sum 的值应当等于 value*n 。

但当n足够大时,会出现 sum += value 的结果依然是 sum 的精度错误。这是因为浮点数表示位数有限,对阶操作可能会使小数超出最大可显示范围。

解决求和过程中遇到的 "大数吃小数" 问题,我们可以使用 Kahan求和算法 进行解决。将循环中的 sum += value 替换为如下语句: 

1     y = value - eps
2     t = sum + y
3     eps = (t - sum) - y
4     sum = t

如果 sum 没有大到引起精度损失,第三行的 eps 将会是0,不影响运算;如果 sum 能够引起精度损失,value 将会一次次地累积到 eps 上去 ( 第三行 eps 此时为 -y , y 代表 value + 上一轮 eps ),直到 sum + eps 能够正常计算,不造成响精度损失。

 

posted @ 2021-03-29 16:12  HarryPotterIsDead!  阅读(1408)  评论(0编辑  收藏  举报