“Double-double”是a representation of numbers as the sum of two double-precision numbers,在有效数字中没有重叠。这种表示利用了现有的双精度硬件实现“近四倍精度”计算。
双重实现中的一个典型低级C函数可能需要两个双精度数字a
和b
|a| ≥ |b|
并计算双重数{{1}代表他们的总和:
(s, e)
(改编自this article。)
这些实现通常采用舍入到最接近偶数模式。
在上面的计算中,s = a + b;
e = b - (s - a);
只是因为这个假设而被归一化为双重。如果没有它,使用(s, e)
,a == 0x1.0p60
,在向上向上模式中,b == 1
计算为s
,0x1.0000000000001p60
计算为e
以上。它们的总和等于-0x0.0000000000001p60
和a
的数学和,但它们的有效数重叠。
一方面取b
和a == 0x1.0p120
和a
的数学总和,另一方面取b
和s
甚至不重合更多。
有没有办法构建一个双重类似的库,其具有与典型的双重库具有舍入到最接近均匀(即相对快速且相对准确)的相同属性,但是有效无论舍入模式是什么?
这样的图书馆是否已经存在?
双重排序的实现用于实现正确舍入的基本函数库的中间计算。因此,以这种方式实施的库往往fail spectacularly when a function is called while the FPU is not in round-to-nearest-even mode。由于性能原因以及因为在执行功能时到达的信号将使FPU处于舍入到最接近均匀模式,因此改变函数内部的舍入模式并不是很可取。我认为最简单的方法是在任何舍入模式下都有快速,正确舍入的基本函数,如果有人可以某种程度上依赖于在任何舍入模式下工作的双重算法。
答案 0 :(得分:1)
njuffa引用的article提供了下面的函数,与我的问题的符号非常相似,只是在我的问题中用fl (a+b)
表示a+b
:
Two−Sum−toward−zero2 (a, b)
if (|a| < |b|)
swap (a , b)
s = fl (a + b)
d = fl (s − a)
e = fl (b − d)
if(|2 ∗ b|<|d|)
s = a, e = b
return (s, e)
这是针对这种特定基本计算的非常简洁的解决方案,当处于圆向零模式时。它希望能够实现正确舍入的基本函数,至少可以通过提前测试舍入模式并选择单独的算法,或者通过编写适用于所有舍入模式的非常谨慎的代码来实现。