dav*_*361 6 c++ floating-point mantissa
有人告诉我,doubleC++ 中的 a 有一个尾数,能够安全、准确地表示 [-(2 53 \xe2\x88\x92 1), 2 53 \xe2\x88\x92 1] 整数。
当尾数只有 52 位时,这怎么可能呢?为什么 anint16只能具有 [-32,768, +32,767] 或 [-2 15 , 2 15 -1] 的范围,而同样的东西可以用来int16允许两倍的可表示数字?
(64位)的格式double如下:
1 bit: sign
11 bits: exponent
52 bits: mantissa
Run Code Online (Sandbox Code Playgroud)
我们只需要查看可以用尾数表示的正整数,因为符号位为我们处理负整数。
天真地,用 52 位,我们可以存储从 0 到 2^52 - 1 的无符号整数。使用符号位,这让我们可以存储从-2^52 - 1到2^52 - 1。
不过,我们有一个可以使用的小技巧。我们说整数的第一个数字始终是1,这给了我们一个额外的位来使用。
为了了解其原理,让我们更深入地研究一下。
1每个正整数在其二进制表示中都至少有一个。因此,我们使用指数向左或向右移动尾数,直到开始时得到 1。一个例子可能会有所帮助:
9、表示为unsigned int:(000...0001001点代表多个0s)。
另一种写法:1.001 * 2^3. (1.001是二进制,不是十进制。)
而且,我们同意永远不使用 0 作为第一位。因此,即使我们可以将 9 写为0.1001 * 2^4或0.01001 * 2^5,但我们不会。我们同意,当我们以这种格式写出数字时,我们将始终确保使用指数来“移动”位,直到我们以 开头1。
那么,我们需要存储获取的信息9如下:
e: 3
i: 1.001
Run Code Online (Sandbox Code Playgroud)
但如果i总是以 开头1,为什么每次都要写出来呢?让我们保留以下内容:
e: 3
i: 001
Run Code Online (Sandbox Code Playgroud)
正是利用这些信息,我们可以将数字重构为:1.i * 2^e == 9。
当我们达到更大的数字时,我们的“ i”会更大,可能会使用最多 52 位,但我们实际上存储的是53信息位,因为1我们总是有前导。
最后注意:这并不完全是存储在双精度数的指数和尾数中的内容,我已经简化了一些内容以帮助解释,但希望这可以帮助人们理解丢失的位来自哪里。另外,这不包括0,它得到一个特殊的表示(上面使用的技巧不适用于0,因为 的通常表示中0没有任何1s )。
| 归档时间: |
|
| 查看次数: |
300 次 |
| 最近记录: |