为输入浮点数预测 Python 3.6 的 `math.floor` 的输出

Predicting the output of Python 3.6's `math.floor` for input floats

在Python3(我用的是3.6)他们decided to start outputting Integral values.

这给我带来了以下问题。假设我们输入一个大的float

math.floor(4.444444444444445e+85)

这种情况下的输出是

44444444444444447395279681404626730521364975775215375673863470153230912354225773084672

在 Python2.7 中输出曾经是 4.444444444444445e+85.

问题 1:3.6 中的输出是否可重现?换句话说,它是什么?在不同的计算机上多次计算给了我相同的结果。我想那是一个仅取决于输入 4.444444444444445e+85 的值。我的猜测是它是该浮点数的二进制表示的下限。输出的分解为

2^232 × 3 × 17 × 31 × 131 × 1217 × 1933 × 13217

那个因子 2^232 接近科学记数法的 10^70,但我不完全确定。

问题2:我想我知道如何取一个浮点数4.444444444444445e+85,提取它的有效数和指数,并自己产生实际整数值4444444444444445*10 **70 或浮点数 4.444444444444445e+85,在我看来,这似乎是 float(4.444444444444445e+85) 底数的更真实值。有没有一种巧妙的方法来恢复这个(允许我称之为)诚实的地板?

好吧,我收回关于调用'honest'的十进制表示法。由于计算机以二进制形式存储数字,因此将二进制表示形式计算的输出称为诚实是公平的。这个,如果我对问题1的猜测是正确的。

以十六进制显示输出应该会有帮助:

>>> import math
>>> math.floor(4.444444444444445e+85)
44444444444444447395279681404626730521364975775215375673863470153230912354225773084672
>>> hex(_)
'0x16e0c6d18f4bfb0000000000000000000000000000000000000000000000000000000000'

注意所有尾随零!在几乎所有平台上,Python 浮点数由硬件表示,具有包含 53 位的尾数和 2 的幂指数。而且,确实,

>>> (0x16e0c6d18f4bfb).bit_length() # the non-zero part does have 53 bits
53
>>> 0x16e0c6d18f4bfb * 2**232  # and 232 zero bits follow it
44444444444444447395279681404626730521364975775215375673863470153230912354225773084672

所以你得到的整数,在数学上,正好等于你开始的浮点数。另一种查看方式:

>>> (4.444444444444445e85).hex()
'0x1.6e0c6d18f4bfbp+284'

如果您想使用十进制表示法,请参阅 decimal 模块的文档。

编辑:如评论中所述,也许您真正想要的只是

float(math.floor(x))

这将重现相同的结果 Python 2 gave for

math.floor(x)