有人能解释一下这种浮点行为吗?
受到这个问题的启发,我想弄清楚到底发生了什么(我的理解比较直观,但我不太明白为什么会这样)。
我认为问题的关键在于这个(运行的是64位的Python):
>>> sys.maxint
9223372036854775807
>>> float(sys.maxint)
9.2233720368547758e+18
Python使用的是IEEE 754浮点数表示法,这种表示法实际上有53位用于有效数字。不过,按照我的理解,上面例子中的有效数字需要57位(如果去掉隐含的前导1,则需要56位)才能表示。有人能解释一下这个差异吗?
3 个回答
当你把 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 位在浮点数中是不存在的。格式化程序只是把这个数字显示成好像那些位是零一样。
你错了。它只需要1个比特。
>>> (9.2233720368547758e+18).hex()
'0x1.0000000000000p+63'
也许下面的内容能帮助你更好地理解:
>>> hex(int(float(sys.maxint)))
'0x8000000000000000L'
这段代码显示,float(sys.maxint)
实际上是一个2的幂。所以,在二进制中,它的有效数字部分(也叫尾数)就是 1
。在IEEE 754标准中,前面的 1.
是隐含的,因此在计算机内部表示这个数字时,它的有效数字部分全是零。
实际上,表示这个数字的IEEE位模式如下:
0x43E0000000000000
注意,只有前面三个“半字节”(即符号位和指数位)是非零的。有效数字部分完全由零组成。因此,它并不需要56位(实际上也不需要53位)来表示。