这项工作并非微不足道! 它是IEEE浮点表示的一个属性,如果所讨论的数字的大小足够小,则int∘floor=⌊⋅⌋,但int(floor(2.3))可能为1时可能有不同的表示。
这篇文章解释了为什么它在这个范围内工作。
在double中,您可以毫无问题地表示32位整数。 不存在任何舍入问题。 更确切地说,双精度数可以表示253和-253之间的所有整数。
简短说明:双精度数最多可存储53个二进制数字。 当您需要更多时,数字会在右侧用零填充。
因此,53个是没有填充可以存储的最大数字。 当然,可以准确地存储需要较少数字的所有(整数)数字。
添加一个到111(省略)111(53个)产生100 ... 000,(53个零)。 我们知道,我们可以存储53位数字,这使得最右边的零填充。
这是253来自的地方。
更多细节:我们需要考虑IEEE-754浮点的工作原理。
1 bit 11 / 8 52 / 23 # bits double/single precision
[ sign | exponent | mantissa ]
然后按如下方式计算该数字(不包括此处无关的特殊情况):
-1sign×1.mantissa×2exponent - bias
其中bias = 2exponent - 1 - 1,即1023和127分别表示双精度/单精度。
知道乘以2X简单地将所有位X移位到左侧,很容易看出任何整数必须将尾数中的所有位都以小数点右边的结尾为零。
除零以外的任何整数都具有以下二进制形式:
1x ... x其中x-es表示MSB右侧的位(最高有效位)。
因为我们排除了零,所以总会有一个MSB,这就是为什么它没有被存储。 要存储整数,我们必须将其带入上述形式:-1sign×1.mantissa×2exponent - bias。
这就像将位移到小数点上一样,直到只有MSB左侧的MSB。 然后将小数点右侧的所有位存储在尾数中。
由此,我们可以看到除了MSB之外我们最多可以存储52个二进制数字。
因此,显式存储所有位的最高数字是
111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles.
为此,我们需要设置指数,使小数点移动52位。 如果我们将指数增加1,我们就不能知道小数点后左边的数字。
111(omitted)111x.
按惯例,它是0.将整个尾数设置为零,我们收到以下数字:
100(omitted)00x. = 100(omitted)000.
这是1,然后是53个零,52个存储,1个由于指数而添加。
它代表253,它标志着我们可以准确表示所有整数的边界(正面和正面)。 如果我们想要将一个加到253,我们必须将隐式零(由x表示)设置为1,但这是不可能的。