假设我有三个32位浮点值,a
,b
和c
,这样(a + b) + c != a + (b + c)
。是否存在可能类似于Kahan summation的求和算法,它保证这些值可以按任何顺序求和,并且总是达到完全相同(相当准确)的总和?我正在寻找一般情况(即不是仅涉及3个数字的解决方案)。
任意精度算术是唯一的出路吗?我正在处理非常大的数据集,所以我想尽可能避免使用任意精度算术的开销。
谢谢!
答案 0 :(得分:8)
有一个有趣的'全精度求和'算法here,它保证最终总和独立于求和的顺序(Python中给出的配方;但翻译起来应该不会太难到其他语言)。请注意,该链接中给出的配方并不完全正确:主累积循环很好,但在最后一步中,将累积的部分和的列表转换为单个浮点结果({的最后一行为了获得正确的舍入结果,需要比简单地求和部分和更加谨慎。{1}}配方)请参阅配方下面的注释和Python的实现(下面链接)以获得解决此问题的方法。
它 使用任意精度算术的形式来保存部分和(中间和被表示为'非重叠'的双倍和),但可能足够快,特别是当所有输入的幅度大致相同。并且它总是给出一个正确的舍入结果,因此准确性与您希望的一样好,并且最终总和与加数的顺序无关。它基于Jonathan Shewchuk的this paper(自适应精确浮点运算和快速稳健几何谓词)。
Python使用此算法实现math.fsum,它执行正确舍入的与顺序无关的求和;你可以看到Python使用的C实现here ---寻找math_fsum函数。
答案 1 :(得分:2)
通过一些关于你必须总和的术语的其他信息,你可以避免Shewchuk算法的开销。
在IEEE 754算术中,只要x-y
(Sterbenz定理,正式证明here)
y/2 <= x <= 2*y
就是精确的
因此,如果您可以在订单中安排所有条款,使得每个部分金额都是上述形式,那么您将免费获得准确的结果。
我担心在实践中几乎没有机会进入确保发生这种情况的条件。交替的正数和负数随着幅度的增加可能会出现这种情况。
注意:原始问题是关于一种算法,无论求和顺序如何,都会产生相同的结果。马克的回答引发了“精确算法”方向的偏差,但是再次阅读你的问题,我担心当我建议重新排序术语时,我正在推动太多事情。你可能不能做你想做的事情,我的回答可能是偏离主题的。好吧,抱歉:)
答案 2 :(得分:-1)
在程序中进行算术运算时,我不太确定(a + b)+ c!= a +(b + c)。
然而,在当今硬件上使用浮点运算的经验法则是永远不要直接测试相等性。
无论你有什么应用,你应该选择一个足够小的epsilon并使用
(abs(a - b) < epsilon)
作为平等测试。