有人可以解释这个浮点行为吗?

时间:2011-03-25 10:56:53

标签: python floating-point ieee-754

受到this question的启发,我试图找出那里究竟发生了什么(我的答案更直观,但我不能完全理解它的原因)。

我相信它归结为此(运行64位Python):

>>> sys.maxint
9223372036854775807
>>> float(sys.maxint)
9.2233720368547758e+18

Python使用IEEE 754浮点表示,有效地为53位有效。但是,据我所知,上面例子中的重要内容需要57位(如果丢弃隐含的前导1,则为56位)。有人可以解释这种差异吗?

3 个答案:

答案 0 :(得分:6)

也许以下内容有助于澄清问题:

>>> hex(int(float(sys.maxint)))
'0x8000000000000000L'

这表明float(sys.maxint)实际上是2的幂。因此,在二进制中,它的尾数恰好是1。在IEEE 754中隐含了前导1.,因此在机器表示中,该数字的尾数由所有零位组成。

实际上,表示此数字的IEEE位模式如下:

0x43E0000000000000

观察到只有前三个半字节(符号和指数)不为零。有效数字完全由零组成。因此,它不需要表示56(也不是53)位。

答案 1 :(得分:2)

你错了。它需要1位。

>>> (9.2233720368547758e+18).hex()
'0x1.0000000000000p+63'

答案 2 :(得分:1)

当你将sys.maxint转换为float或double时,结果正好是0x1p63,因为有效数字只包含24或53位(包括隐含位),因此尾随位会导致向上舍入。 (sys.maxint为2 ^ 63 - 1,向上舍入产生2 ^ 63。)

然后,当您打印此浮动时,某些子例程将其格式化为十进制数字。为此,它计算数字以表示2 ^ 63。它能够打印9.2233720368547758e + 18这一事实并不意味着原始数字包含的区别于9.2233720368547759e + 18。它很简单意味着它中的位确实代表9.2233720368547758e + 18(大约)。实际上,双精度的下一个可表示的浮点数是9223372036854777856(大约9.2233720368547778e + 18),这是2 ^ 63 + 2048.因此这些整数的低11位不存在于double中。格式化程序仅显示数字,就好像这些位为零一样。