使用 numpy.float128 对大于 epsilon 的数字进行添加的错误结果

wrong result on adition of numbers larger than epsilon using numpy.float128

提问人:Falk 提问时间:2/3/2022 最后编辑:petezurichFalk 更新时间:2/3/2022 访问量:105

问:

考虑到 epsilon 是您可以加到 1 的最小数字。

当我执行加法并打印结果时,我得到的是 1 而不是 1+epsilon。

我已经实现了一个函数。我添加了一个用于调试的语句。getEpsilonprint

该函数的实现方式如下:

def getEpsilon():
    a = np.float128(1)
    b = np.float128(1)
    c = np.float128(2)
    while a + b != a:
        b = b / c
        d = a+b
        print (F"b={b:3.50f}, d={d:3.50f}")
    return b * c

在对 while 循环进行多次迭代后,其值仅为 1,但仍计算为 True。da + b != a

这是输出:

b=0.5000000000000000000000000, d=1.5000000000000000000000000
b=0.2500000000000000000000000, d=1.2500000000000000000000000
...
b=0.0000000000000004440892099, d=1.0000000000000004440892099
b=0.0000000000000002220446049, d=1.0000000000000002220446049
b=0.0000000000000001110223025, d=1.0000000000000000000000000
b=0.0000000000000000555111512, d=1.0000000000000000000000000
...
b=0.0000000000000000001084202, d=1.0000000000000000000000000
b=0.0000000000000000000542101, d=1.0000000000000000000000000

为什么有与不同的行为a + b != ad = a+b

看起来有些操作是用 64 位完成的。

如果我用等效的类型重复它,结果是(最后 2 行):float64

b=0.0000000000000002220446049, d=1.0000000000000002220446049
b=0.0000000000000001110223025, d=1.0000000000000000000000000
python numpy 浮点精度

评论

0赞 Kelly Bundy 2/3/2022
尝试打印 。d={d!r}
1赞 CJR 2/3/2022
从文档中np.float128 provide only as much precision as np.longdouble, that is, 80 bits on most x86 machines and 64 bits in standard Windows builds
3赞 Eric Postpischil 2/3/2022
猜想:只能将值打印为 ,而不能。经过 53 次迭代后,in 仍然不是 1,而是将其转换为 rounds 到 1,这就是打印的内容。64 次迭代后,为 1,循环停止。print (F"b={b:3.50f}, d={d:3.50f}")float64float128float128dfloat64d
0赞 Falk 2/4/2022
@KellyBundy,@eric后,你们对字符串格式的看法是正确的。@KellyBundy旗帜成功了。你想把它写成一个答案吗?@cjr我想我得到了一个 80 位变量,但字符串格式化程序将其转换为 64 位变量。这很奇怪,因为我在装有 Linux 的 Ryzen 7 上运行它。!r
1赞 Mark Dickinson 2/4/2022
请参阅 NumPy 源代码中的“TODO”注释。(这是在 . tl;dr - 它首先将底层 C 转换为 ,然后将其移交给 Python 的内置格式。另请参阅 github.com/numpy/numpy/issues/10645,这主要是关于格式化的,但问题的原因是一样的 - 在格式化之前,它也被转换为 Python。float128.__format__long doubledoublefloatfloat32float

答: 暂无答案