什么是最精确的数字分割方法?
考虑(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?