a,b是32位浮点值,N是32位整数,k可以取值0,1,2,... M.需要计算c_k = a +(N + k)* b ;操作需要是32位操作(不是双精度)。关注的是准确性 - 以下哪一项更准确?:
I)c_k = a +(N + k)* b
II)首先计算:c_0 = a + N * b
然后通过加法迭代地计算c_1,c_2等:
c_1 = c_0 + b;
c_2 = c_1 + b;
答案 0 :(得分:3)
链式加法是您可以执行的最差操作之一,因为最后一个结果中的舍入误差将是链中每次加法时单个操作舍入误差的净和。使用第一种方式或使用c_i = c_0 + b*i
会更准确。
答案 1 :(得分:2)
由于您似乎并不关心操作次数,因此假设IEEE 754型号可以使用32位操作完全执行。
请参阅Shewchuck自适应精度浮点运算和快速稳健几何谓词 - http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf或http://www-2.cs.cmu.edu/afs/cs/project/quake/public/papers/robust-arithmetic.ps
您可以定义两个精确的操作(参见论文)
(product,residue) = twoproduct(a,b)
(sum,residue) = twosum(a,b)
然后你必须将N + k分解为两个24位有效数,例如
NkH = (N+k) / 256;
NkL = (N+K) % 256;
然后你有两个可能不精确的乘法
( HH , HL ) = twoproduct( NkH , b)
( LH , LL ) = twoproduct( NkL , b)
然后你可以求和(HH,HL)+(LH,LL)+ a
这可以通过快速扩展和完全执行(再次参见论文)
(c1,c2,c3,c4,c5) = sort_increasing_magnitude(HH,HL,LH,LL,a)
(s2,s1) = twosum( c2,c1 )
(s3,s2) = twosum( c3,s2 )
(s4,s3) = twosum( c4,s3 )
(s5,s4) = twosum( c5,s4 )
然后,您可以在s5中获得完全舍入的结果,就像使用无限精度算术执行操作一样。