什么是最精确的数字分割方法?
考虑(ab)/(cd)操作,其中a , b , c和d是浮点数(即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
这是有效的,因为如果我们让rr是r计算中的误差(即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?
