简体   繁体   English

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

[英]Can someone explain this floating-point behavior?

Inspired by this question , I was trying to find out what exactly happens there (my answer was more intuitive, but I cannot exactly understand the why of it). 这个问题的启发,我试图找出那里到底发生什么 (我的答案更直观,但我不能完全理解它的原因)。

I believe it comes down to this (running 64 bit Python): 我相信它归结为此(运行64位Python):

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

Python uses the IEEE 754 floating-point representation, which effectively has 53 bits for the significant. Python使用IEEE 754浮点表示,有效地为53位。 However, as far as I understand it, the significant in the above example would require 57 bits (56 if you drop the implied leading 1) to be represented. 但是,据我所知,上面例子中的重要内容需要57位(如果丢弃隐含的前导1,则为56位)。 Can someone explain this discrepancy? 有人可以解释这种差异吗?

Perhaps the following will help clear things up: 也许以下内容有助于澄清问题:

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

This shows that float(sys.maxint) is in fact a power of 2. Therefore, in binary its mantissa is exactly 1 . 这表明float(sys.maxint)实际上是2的幂。因此,在二进制中,它的尾数恰好为1 In IEEE 754 the leading 1. is implied, so in the machine representation this number's mantissa consists of all zero bits. 在IEEE 754中,隐含了前导1.因此在机器表示中,该数字的尾数由所有零比特组成。

In fact, the IEEE bit pattern representing this number is as follows: 实际上,表示此数字的IEEE位模式如下:

0x43E0000000000000

Observe that only the first three nibbles (the sign and the exponent) are non-zero. 观察到只有前三个半字节(符号和指数)不为零。 The significand consists entirely of zeroes. 有效数字完全由零组成。 As such it doesn't require 56 (nor indeed 53) bits to be represented. 因此,它不需要表示56(也不是53)位。

You're wrong. 你错了。 It requires 1 bit. 它需要1位。

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

When you convert sys.maxint to a float or double, the result is exactly 0x1p63, because the significand contains only 24 or 53 bits (including the implicit bit), so the trailing bits cause a round up. 当您将sys.maxint转换为float或double时,结果正好是0x1p63,因为有效位数仅包含24或53位(包括隐含位),因此尾随位会导致向上舍入。 (sys.maxint is 2^63 - 1, and rounding it up produces 2^63.) (sys.maxint为2 ^ 63 - 1,向上舍入产生2 ^ 63。)

Then, when you print this float, some subroutine formats it as a decimal numeral. 然后,当您打印此浮动时,某些子例程将其格式化为十进制数字。 To do this, it calculates digits to represent 2^63. 为此,它计算数字以表示2 ^ 63。 The fact that it is able to print 9.2233720368547758e+18 does not imply that the original number contains bits that would distinguish it from 9.2233720368547759e+18. 它能够打印9.2233720368547758e + 18这一事实并不意味着原始数字包含的区别于9.2233720368547759e + 18。 It simple means that the bits in it do represent 9.2233720368547758e+18 (approximately). 它很简单意味着它中的位确实代表9.2233720368547758e + 18(大约)。 In fact, the next representable floating-point number in double precision is 9223372036854777856 (approximately 9.2233720368547778e+18), which is 2^63 + 2048. So the low 11 bits of these integers are not present in the double. 实际上,双精度的下一个可表示的浮点数是9223372036854777856(大约9.2233720368547778e + 18),这是2 ^ 63 + 2048.因此这些整数的低11位不存在于double中。 The formatter merely displays the number as if those bits are zero. 格式化程序仅显示数字,就好像这些位为零一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM