对FPU舍入模式具有弹性的双重实现

时间:2013-04-06 16:35:11

标签: floating-point ieee-754

上下文:双倍算术

“Double-double”是a representation of numbers as the sum of two double-precision numbers,在有效数字中没有重叠。这种表示利用了现有的双精度硬件实现“近四倍精度”计算。

双重实现中的一个典型低级C函数可能需要两个双精度数字ab |a| ≥ |b|并计算双重数{{1}代表他们的总和:

(s, e)

(改编自this article。)

这些实现通常采用舍入到最接近偶数模式。

在上面的计算中,s = a + b; e = b - (s - a); 只是因为这个假设而被归一化为双重。如果没有它,使用(s, e)a == 0x1.0p60,在向上向上模式中,b == 1计算为s0x1.0000000000001p60计算为e以上。它们的总和等于-0x0.0000000000001p60a的数学和,但它们的有效数重叠。

一方面取ba == 0x1.0p120a的数学总和,另一方面取bs甚至不重合更多。

问题

有没有办法构建一个双重类似的库,其具有与典型的双重库具有舍入到最接近均匀(即相对快速且相对准确)的相同属性,但是有效无论舍入模式是什么?

这样的图书馆是否已经存在?

更一般的上下文:正确舍入的基本函数

双重排序的实现用于实现正确舍入的基本函数库的中间计算。因此,以这种方式实施的库往往fail spectacularly when a function is called while the FPU is not in round-to-nearest-even mode。由于性能原因以及因为在执行功能时到达的信号将使FPU处于舍入到最接近均匀模式,因此改变函数内部的舍入模式并不是很可取。我认为最简单的方法是在任何舍入模式下都有快速,正确舍入的基本函数,如果有人可以某种程度上依赖于在任何舍入模式下工作的双重算法。

1 个答案:

答案 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)

这是针对这种特定基本计算的非常简洁的解决方案,当处于圆向零模式时。它希望能够实现正确舍入的基本函数,至少可以通过提前测试舍入模式并选择单独的算法,或者通过编写适用于所有舍入模式的非常谨慎的代码来实现。