Kahan 求和
简介¶
Kahan 求和 算法,又名补偿求和或进位求和算法,是一个用来 降低有限精度浮点数序列累加值误差 的算法。它主要通过保持一个单独变量用来累积误差(常用变量名为
该算法主要由 William Kahan 于 1960s 发现。因为 Ivo Babuška 也曾独立提出了一个类似的算法,Kahan 求和算法又名为 Kahan-Babuška 求和算法。
舍入误差¶
在计算机程序中,因为电脑的内存不是无限的,无限实数实际上并不能用无限内存表示。很多时候我们需要将无限实数压缩为有限位数做近似表示。大多数程序最多存储
在浮点加法计算中,交换律(commutativity)成立,但结合律(associativity)不成立。也就是说,
为了得到更准确的浮点累加结果,我们需要使用 Kahan 求和算法。
在计算
算法¶
Kahan 求和算法主要通过一个单独变量用来累积误差。如下方参考代码所示,
因为
参考代码
1 2 3 4 5 6 7 8 9 10 11 | float kahanSum(vector<float> nums) {
float sum = 0.0f;
float c = 0.0f;
for (auto num : nums) {
float y = num - c;
float t = sum + y;
c = (t - sum) - y;
sum = t;
}
return sum;
}
|
习题¶
在 OI 中,Kahan 求和主要作为辅助工具存在,为计算结果提供误差更小的值。
例题 CodeForces Contest 800 Problem A. Voltage Keepsake
有
例题 CodeForces Contest 504 Problem B. Misha and Permutations Summation
定义数字
编程语言的求和¶
Python 的标准库指定了精确舍入求和的 fsum 函数可用于返回可迭代对象中值的准确浮点总和,它通过使用 Shewchuk 算法跟踪多个中间部分和来避免精度损失。
Julia 语言中,sum 函数的默认实现是成对求和,以获得高精度和良好的性能。同时外部库函数 sum_kbn 为需要更高精度的情况提供了 Neumaier 变体的实现,具体可见 KahanSummation.jl。
参考资料与注释¶
- Kahan_summation_algorithm - Wikipedia
- Kahan summation - Rosetta Code
- VK Cup Round 2 + Codeforces Round 409 Announcement
- Rounding off errors in Java - GeeksforGeeks
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用