提问人:Pascal Cuoq 提问时间:4/7/2013 最后编辑:phuclvPascal Cuoq 更新时间:9/10/2020 访问量:402
双双实现,可灵活应对 FPU 舍入模式
double-double implementation resilient to FPU rounding mode
问:
上下文:双双算术
“双精度”是数字的表示形式,表示为两个双精度数的总和,在有效数中没有重叠。这种表示利用现有的双精度硬件实现进行“接近四精度”的计算。
双精度实现中的一个典型低级 C 函数可能采用两个双精度数,并计算表示其总和的双精度数:a
b
|a| ≥ |b|
(s, e)
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
e
问题
有没有办法构建一个双双的库,其属性与典型的双双库在四舍五入到最接近偶数(即相对较快和相对准确)中具有的属性相同,但无论舍入模式如何?
这样的库已经存在了吗?
更一般的上下文:正确舍入的基本函数
double-double 排序的实现用于正确舍入初等函数库的实现中的中间计算。因此,当 FPU 未处于舍入到最接近偶数模式时调用函数时,以这种方式实现的库往往会失败。出于性能原因,并且由于函数执行时到达的信号会使 FPU 处于舍入到最接近偶数模式,因此更改函数内部的舍入模式不是很可口。在我看来,在任何舍入模式下都能快速、正确舍入的基本函数的最简单方法是,如果人们可以以某种方式依赖在任何舍入模式下工作的双倍算术。
答:
njuffa 提到的文章提供了以下功能,其符号与我的问题非常相似,只是在那里表示的内容只是在我的问题中表示: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)
对于在四舍五入到零模式下的这种特定基本计算,这是一个非常巧妙的修复。它使人们希望实现一个正确的舍入基本函数是可能的,至少通过尽早测试舍入模式并选择单独的算法,或者通过编写适用于所有舍入模式的非常谨慎的代码。
评论