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 能够正常计算,不造成响精度损失。