什么是最精确的数字分割方法?

考虑(ab)/(cd)操作,其中abcd是浮点数(即C ++中的double类型)。 (ab)(cd)都是( sum - correction )对,如在Kahan求和算法中。 简而言之,这些( sum - correction )对的具体情况是该sum包含相对于正在correction的大的值。 更确切地说,由于数字限制( double比特中的53位尾数), correction包含sum期间不适合的sum

考虑到上述数字的特殊性,计算(ab)/(cd)的数值最精确的方法是什么?

奖金问题:最好将结果作为( sum - correction ),就像在Kahan求和算法中那样。 所以要找到(ef)=(ab)/(cd) ,而不仅仅是e=(ab)/(cd)


Dekker(1971)的div2算法是一个很好的方法。

它需要一个mul12(p,q)算法,它可以准确地计算一对u+v = p*q 。 Dekker使用了一种称为Veltkamp分裂的方法,但是如果您有权访问fma函数,那么更简单的方法是

u = p*q
v = fma(p,q,-u)

实际的分裂看起来像(我必须改变一些标志,因为Dekker使用添加剂对而不是减法):

r   = a/c
u,v = mul12(r,c)
s   = (a - u - v - b + r*d)/c

总和r+s是对(ab)/(cd)的精确近似。

更新:减法和加法被认为是左联合的,即

s = ((((a-u)-v)-b)+r*d)/c

这是有效的,因为如果我们让rrr计算中的误差(即r + rr = a/c ),那么由于u+v = r*c恰好,我们有rr*c = auv ,所以因此(auvb)/c给出了(ab)/c的修正项的相当好的近似。

最终r*d由于以下原因而产生:

(a-b)/(c-d) = (a-b)/c * c/(c-d) = (a-b)/c *(1 + d/(c-d)) 
            = [a-b + (a-b)/(c-d) * d]/c

现在r对于(ab)/(cd)也是一个相当好的初始近似值,所以我们将其替换为[...] ,所以我们发现(auv-b+r*d)/c(ab)/(cd)修正项


对于微小的更正,可能会想到

(a - b) / (c - d) = a/b (1 - b/a) / (1 - c/d) ~ a/b (1 - b/a + c/d)
链接地址: http://www.djcxy.com/p/37295.html

上一篇: What is the most numerically precise method for dividing sums or differences?

下一篇: Computing integer absolute differences in overflow