Kahan summation algorithm

In numerical analysis, theKahan summation algorithm (also known ascompensated summation) significantly reduces thenumerical error in the total obtained by adding asequence of finiteprecisionfloating point numbers, compared to the obvious approach.

该算法是数值分析中的算法,用来减少浮点数累加和的数值误差,可以在高性能计算对浮点精度要求高的过程中使用。

原理:This is done by keeping a separate running compensation (a variable to accumulate small errors). 例子中所使用的c

例子如下: 

假定我们使用六位有效数字的十进制浮点算法来累加, 第一个值:10000.0,第二个值为: 3.14159,第三个值为:2.71828。那么它们 精确和应该是 10005.85987, 四舍五入为:10005.9. 然而普通的算法,前两个数相加约分后为:10003.1. 然后再和第三个数相加约分后为 10005.8,结果错误。

例子中的计算过程如下(c 初始为0):

  y = 3.14159 - 0                   y = input[i] - c
  t = 10000.0 + 3.14159
    = 10003.1                       Many digits have been lost!
  c = (10003.1 - 10000.0) - 3.14159 This must be evaluated as written! 
    = 3.10000 - 3.14159             The assimilated part of y recovered, vs. the original full y.
    = -.0415900                     Trailing zeros shown because this is six-digit arithmetic.
sum = 10003.1                       Thus, few digits from input(i) met those of sum.


 

  y = 2.71828 - -.0415900           The shortfall from the previous stage gets included.
    = 2.75987                       It is of a size similar to y: most digits meet.
  t = 10003.1 + 2.75987             But few meet the digits of sum.
    = 10005.85987, rounds to 10005.9
  c = (10005.9 - 10003.1) - 2.75987 This extracts whatever went in.
    = 2.80000 - 2.75987             In this case, too much.
    = .040130                       But no matter, the excess would be subtracted off next time.
sum = 10005.9                       Exact result is 10005.85987, this is correctly rounded to 6 digits.


 

算法伪代码如下:

function KahanSum(input)
    var sum = 0.0
    var c = 0.0          //A running compensation for lost low-order bits.
    for i = 1 to input.length do
        y = input[i] - c    //So far, so good: c is zero.
        t = sum + y         //Alas, sum is big, y small, so low-order digits of y are lost.
        c = (t - sum) - y   //(t - sum) recovers the high-order part of y; subtracting y recovers -(low part of y)
        sum = t             //Algebraically, c should always be zero. Beware eagerly optimising compilers!
        //Next time around, the lost low part will be added to y in a fresh attempt.
    return sum


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值