是否有一种亚 O(n) 的方法1 可以复制 IEEE 754 算术中浮点值的重复求和?
也就是说,是否有一种更快的方法来完全2复制以下伪代码的结果:
f64 notQuiteFMA(f64 acc, f64 f, bigint n) {
for (bigint i = 0; i < n; i++) {
acc = acc + f;
}
return acc;
}
?3
在实际算术中,答案很简单 -
return acc + f*n
就足够了。然而,在有限精度下,答案要复杂得多。作为一个例子,请注意 notQuiteFMA(0, 1, 1 << 256)
约为 4 2^53,而不是人们期望的无限精度的 2^256。 (这个例子还说明了为什么加快计算速度可能是可取的 - 计数到 2^256 是相当不切实际的。)
acc
和 f
的每个初始值存储整个前缀和最终循环中的步数。 )x + 1 == x
首先出现在 2^53 左右。我相信确切的值取决于舍入模式。我可以回答这个问题,尽管我认为你不会喜欢它。
一旦数字达到 53 个有效位,该值将停止递增。我们可以计算一下。下面是一个 Python 脚本,显示了向浮点数加 1 不再改变浮点数的点:
import struct
j = 1
for i in range(1,58):
j = 2*j
r = float(j)
s = r+1
if r == s:
pat = struct.pack('>d',r)
print(pat.hex())
print(i,j,r,s)
break
输出:
4340000000000000
53 9007199254740992 9007199254740992.0 9007199254740992.0
第一行是该值的十六进制表示。