提问人:Nico Schlömer 提问时间:2/21/2018 最后编辑:AndrewNico Schlömer 更新时间:2/27/2022 访问量:175
A+B+C 的 add3 指令,单次舍入
add3 instruction for a+b+c with one single rounding
问:
背景
众所周知,两个浮点数的确切乘积并不总是浮点数,但误差是。一些精确乘法代码通过返回两个数字来利用这一点exact(a*b) - float(a*b)
res = a * b
err = fma(a, b, -res)
这利用了 fused-multiply-add 指令,该指令以一次舍入返回表达式。(a*b)+c
问题
现在,我想对总和做同样的事情,即
res = a + b
err = add3(a, b, -res)
add3
应该返回一个四舍五入的表达式。(a+b)+c
除了这篇文章之外,我无法找到现实世界中实际存在的提示。add3
是否有包含 的 CPU 指令集?有没有语言实现它?add3
答:
问题中请求的 和 由 Jean-Michel Muller 等人的《浮点算术手册》中的 Fast2Sum 算法提供,Birkhäuser,2009 年,第 126 页,第 4.3.1 节“Fast2Sum 算法”。该书将其归功于 1971 年的 Dekker,而 Kahan 在 1965 年更早地介绍了它的运作:err
res
给定一个底数小于或等于 3 的浮点格式,具有次正态数,以及 numbers 并可用该格式表示 ||≥ ||,然后使用四舍五入到最接近:a
b
a
b
s = a+b;
z = s-a;
t = b-z;
计算,例如最接近 + 和 + = + 的浮点数。(因此,和是问题中请求的和。s
t
s
a
b
s
t
a
b
s
t
res
err
||≥ ||绰绰有余;该算法只要求 的浮点指数至少是 的指数,但仅仅比较这些值可能更容易。因此,一个完整的实现需要类似于上述代码之前的内容。a
b
a
b
if (fabs(b) > fabs(a)) swap(&a, &b);
书中有一个证据。(证明有一个勘误表;它假设,在不损失一般性的情况下,> 0。这可能会在第二版中得到纠正。a
这不提供建议的一般功能,仅提供特定情况。 由 Boldo 和 Melquiond 在第 201 页第 6.3.4 节中的函数提供。它操纵浮点数的编码,这引发了性能和可移植性问题。这种操作仅限于递增或递减,因此标准 C 函数可以代替它,尽管这对性能来说不一定更好。add3
add3
CorrectRoundedSum3
nexttoward
评论
add3
add3(a, b, -s)
评论
sse
fma()
add3
fma
sse
add3
err
res