algorithm - 除和或除差的最精确的数值方法是什么?

标签 algorithm floating-point sum numeric division

考虑 (a-b)/(c-d)操作,其中 a , b , cd是 float (即 C++ 中的 double 类型)。两者 (a-b)(c-d)是 ( sum - correction ) 对,如 Kahan summation algorithm .简而言之,这些 ( sum - correction ) 对的具体是 sum包含相对于 correction 中的值较大的值.更准确地说,correction包含不适合 sum 的内容由于数值限制(double 类型中的 53 位尾数)在求和期间。

计算(a-b)/(c-d) 的最精确的数值方法是什么?鉴于数字的上述特殊性?

奖金问题:最好将结果也作为 ( sum - correction ),如 Kahan 求和算法。于是去找(e-f)=(a-b)/(c-d) , 而不仅仅是 e=(a-b)/(c-d) .

最佳答案

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

它需要一个 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(a-b)/(c-d) 的精确近似值.

更新:假设减法和加法是左结合的,即

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

这是可行的,因为如果我们让 rrr 的计算错误(即 r + rr = a/c 准确),然后自 u+v = r*c确切地说,我们有 rr*c = a-u-v正是,因此 (a-u-v-b)/c(a-b)/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也是 (a-b)/(c-d) 的一个相当好的初始近似值所以我们在 [...] 中替换它, 所以我们发现 (a-u-v-b+r*d)/c(a-b)/(c-d) 的校正项的良好近似值。

关于algorithm - 除和或除差的最精确的数值方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38931858/

相关文章:

php - mysql 的输出总和 - 不正确的值

SQL 查询多张表的 Sum 和 Count

algorithm - 摊销和平均运行时复杂度

algorithm - 约翰卡马克不寻常的快速平方根反函数(Quake III)

C#:将 float 表达式转换为 int 时结果错误

java - 添加文本文件中的值

algorithm - 不使用数组递归创建所有子集

c++ - 给定n个数,写一个例程找出4个连续数中最大的数

algorithm - 归并排序怎么可能有多个big-oh值呢?

floating-point - 用极限分母使数有理化