与小于无穷大的最大浮点数相加得到无穷大的最小数是多少?

Her*_*llo 0 python floating-point

python中最大的数字应该是:

\n
l=2**(1023)*(2-2**(-52))\n
Run Code Online (Sandbox Code Playgroud)\n
\n

1.7976931348623157e+308

\n
\n

这可以通过指令验证:

\n
sys.float_info.max\n
Run Code Online (Sandbox Code Playgroud)\n
\n

1.7976931348623157e+308

\n
\n

不过请看下面的内容

\n
1.0000000000000000000000000001*l\n
Run Code Online (Sandbox Code Playgroud)\n
\n

1.7976931348623157e+308

\n
\n

现在:

\n
1.00006*l\n
Run Code Online (Sandbox Code Playgroud)\n
\n

信息

\n
\n

到底是怎么回事?对于哪个x发生 (1+ x -\xce\xb5) = 1.7976931348623157e+308 且 (1+ x ) = inf?

\n

更新:

\n

我相信在Python中触发无穷大的最大数字是

\n

sys.float_info.max + 0.5*epsilonsys.float_info.max + 0.51*epsilon

\n

其中 epsilon = $2^{-52}$ 是计算机的 epsilon。

\n

看看这个:

\n
l = sys_float_info.max\n(1+0.5*epsilon)*l\n
Run Code Online (Sandbox Code Playgroud)\n
\n

1.7976931348623157e+308

\n
\n
(1+0.51*epsilon)*l\n
Run Code Online (Sandbox Code Playgroud)\n
\n

信息

\n
\n

Tim*_*ers 5

在第一种情况下,您实际上正好乘以 1:

>>> 1.0000000000000000000000000001
1.0
Run Code Online (Sandbox Code Playgroud)

二进制浮点不是所见即所得 - 它在所有阶段都会四舍五入到机器精度。

继续上面的内容:

>>> 1.0000000000000001
1.0
>>> 1.000000000000001
1.000000000000001
Run Code Online (Sandbox Code Playgroud)

因此1.000000000000001,这种形式的最小文字不会精确舍入为 1.0。进而:

>>> sys.float_info.max * 1.000000000000001
inf
Run Code Online (Sandbox Code Playgroud)

请注意,乘以大于 1 的最小可表示浮点就足够了,该浮点数比该文字的舍入值稍小:

>>> import math
>>> math.nextafter(1.0, 100) * sys.float_info.max
inf
>>> 1.000000000000001 > math.nextafter(1.0, 100)
True
Run Code Online (Sandbox Code Playgroud)

那加法呢?

虽然示例显示了乘法,但问题的标题询问的是加法。那么我们也这样做吧。了解nextafter()ulp(),它们是解决此类问题的正确工具。首先,找到最大有限可表示浮点数的简单计算方法:

>>> import math
>>> big = math.nextafter(math.inf, 0)
>>> big
1.7976931348623157e+308
Run Code Online (Sandbox Code Playgroud)

现在设置lastbit为其最低有效位的值:

>>> lastbit = math.ulp(big)
>>> lastbit
1.99584030953472e+292
Run Code Online (Sandbox Code Playgroud)

当然,如果我们添加它,big它就会溢出到无穷大。确实如此:

>>> big + lastbit
inf
Run Code Online (Sandbox Code Playgroud)

然而,即使添加一半也会溢出,因为“到最接近/偶数”舍入解决了中途平局“向上”的问题:

>>> big + lastbit / 2.0
inf
Run Code Online (Sandbox Code Playgroud)

更小的东西会起作用吗?不会。任何较小的值都会因“向下”四舍五入而被丢弃。这里我们尝试添加下一个最小的可表示浮点,并发现它没有效果:

>>> big + math.nextafter(lastbit / 2.0, 0)
1.7976931348623157e+308
Run Code Online (Sandbox Code Playgroud)