为什么浮点尾数的位宽表示的数字是int的两倍



我听说C++中的double有一个尾数,能够安全准确地表示[-(253−1(,253−1]整数。

当尾数只有52位时,这怎么可能呢?为什么int16只能具有[-32768,+32767]或[-215,225-1]的范围,而int16可以使用相同的东西来允许两倍多的可表示数?

double(64位(的格式如下:

1 bit: sign
11 bits: exponent
52 bits: mantissa

我们只需要看看我们可以用尾数表示的正整数,因为符号位为我们处理负整数。

简单地说,使用52位,我们可以存储从0到2^52-1的无符号整数。通过一个符号位,我们可以存储从-2^52 - 12^52 - 1的内容。

然而,我们有一个小技巧可以使用。我们说整数的第一个数字是总是一个1,这给了我们一个额外的比特。

要了解为什么这样做有效,让我们深入了解一下。

每个正整数在其二进制表示中将至少有一个1。所以,我们向左或向右移动尾数,直到开始时使用指数得到1。这里有一个例子可能会有所帮助:

9,表示为无符号int:000...0001001(表示更多0s的点(。

另一种写法:1.001 * 2^3。(1.001是二进制的,而不是十进制的。(

而且,我们同意永远不要使用0作为第一位。所以,即使我们可以把9写成0.1001 * 2^40.01001 * 2^5,我们也不会。我们一致认为,当我们以这种格式写出数字时,我们将始终确保使用指数来";移位";直到我们从CCD_ 14开始。

因此,我们需要存储以下信息才能获得9

e: 3
i: 1.001

但是,如果i总是以1开头,为什么每次都要把它写出来呢?让我们只保留以下内容:

e: 3
i: 001

正是利用这些信息,我们可以将数字重建为:1.i * 2^e == 9

当我们达到更大的数字时;CCD_ 19";会更大,可能最多使用52位,但我们实际上存储的是53位的信息,因为我们一直拥有领先的1

最后一点:这不是完全双精度的指数和尾数中存储的内容,我简化了一些内容来帮助解释,但希望这能帮助人们理解缺失的部分来自哪里。此外,这还不包括获得特殊表示的0(上面使用的技巧对0不起作用,因为0的通常表示中没有任何1s(。

最新更新