【发布时间】:2015-07-26 00:42:28
【问题描述】:
64 位中有多少位分配给双精度整数部分和小数部分。或者有什么规则可以指定?
【问题讨论】:
-
浮点没有整数和小数部分。这就像科学记数法。最常见的双精度格式的普通数字有一个 11 位二进制指数,修改了 1.x 形式的有效数字,其中 x 是 52 位。
标签: c types floating-point double
64 位中有多少位分配给双精度整数部分和小数部分。或者有什么规则可以指定?
【问题讨论】:
标签: c types floating-point double
注意:我知道我已经回复了评论。这是为了我自己和 OP 一样的利益;当我试图解释它时,我总是会学到一些新东西。
浮点值(不考虑精度)表示如下:
<em>sign</em> * <em>significand</em> * β<sup><em>exp</em></sup>
其中 sign 是 1 或 -1,β 是 底数,exp 是整数指数,并且significand 是分数。在这种情况下,β 是 2。例如,实际值3.0 可以表示为1.10<sub>2</sub> * 2<sup>1</sup>,或0.11<sub>2</sub> * 2<sup>2</sup>,甚至0.011<sub>2</sub> * 2<sup>3</sup>。
请记住,二进制数是 2 的幂的和,从左到右依次递减。例如,101<sub>2</sub> 等价于 1 * 2<sup>2</sup> + 0 * 2<sup>1</sup> + 1 * 2<sup>0</sup>,它为我们提供了值 5。您可以使用 2 的负幂将其扩展到小数点,因此 101.11<sub>2</sub> 相当于
1 * 2<sup>2</sup> + 0 * 2<sup>1</sup> + 1 * 2<sup>0</sup> + 1 * 2<sup><strong>-1</strong></sup> + 1 * 2<sup><strong>-2</strong></sup>
这给了我们十进制值5.75。浮点数被规范化,因此在小数点之前有一个非零数字,因此我们将其写为1.0111<sub>2</sub> * 2<sup>2</sup>,而不是将5.75写成101.11<sub>2</sub>
这是如何以 32 位或 64 位二进制格式编码的?确切的格式取决于平台;大多数现代平台使用 IEEE-754 规范(它还指定了浮点运算的算法,以及无穷大和非数字 (NaN) 等特殊值),但是一些较旧的平台可能使用它们自己的专有格式(例如VAX G 和 H 扩展精度浮点数)。我认为 x86 还具有用于中间计算的专有 80 位格式。
总体布局如下所示:
seeeeeeee...ffffffff....
其中s 表示符号位,e 表示专用于指数的位,f 表示专用于有效数或分数的位。 IEEE-754 32 位单精度布局是
seeeeeeeefffffffffffffffffffffff
这为我们提供了一个 8 位指数(可以表示值 -126 到 127)和一个 22 位有效数(给我们大约 6 到 7 个有效十进制数字)。符号位中的0 表示正值,1 表示负值。对指数进行编码,使得00000001<sub>2</sub> 表示-126,01111111<sub>2</sub> 表示0,11111110<sub>2</sub> 表示127(00000000<sub>2</sub> 保留用于表示0 和“非规范化”数字,而@987654358 @ 保留用于表示无穷大和 NaN)。此格式还假定隐藏的前导小数位始终设置为1。因此,我们表示为 1.0111<sub>2</sub> * 2<sup>2</sup> 的值 5.75 将被编码为 32 位单精度浮点数为
01000000101110000000000000000000
|| || |
|| |+----------+----------+
|| | |
|+--+---+ +------------ significand (1.0111, hidden leading bit)
| |
| +---------------------------- exponent (2)
+-------------------------------- sign (0, positive)
IEEE-754 双精度浮点数使用 11 位作为指数(-1022 到 1023),使用 52 位作为有效数。我不会费心把它写出来(这篇文章正在变成一本小说)。
由于指数,浮点数的范围大于整数;指数 127 只需要 8 位来编码,但 2<sup>127</sup> 代表一个 38 位 十进制数。指数中的位数越多,可以表示的值范围就越大。 precision(有效位数)由有效数字中的位数决定。有效数字中的位数越多,您可以表示的有效数字就越多。
大多数实数值不能准确地表示为浮点数;您不能将无限数量的值压缩到有限数量的位中。因此,可表示的浮点值之间存在差距,并且大多数值将是近似值。为了说明问题,我们来看一个 8 位“四分之一精度”格式:
seeeefff
这为我们提供了一个介于 -7 和 8 之间的指数(我们不会担心诸如无穷大和 NaN 之类的特殊值)和一个带有隐藏前导位的 3 位有效数字。我们的指数越大,可表示值之间的差距就越大。这是一个显示问题的表格。左栏是有效数;每个额外的列都显示了我们可以为给定指数表示的值:
sig -1 0 1 2 3 4 5
--- ---- ----- ----- ----- ----- ----- ----
000 0.5 1 2 4 8 16 32
001 0.5625 1.125 2.25 4.5 9 18 36
010 0.625 1.25 2.5 5 10 20 40
011 0.6875 1.375 2.75 5.5 11 22 44
100 0.75 1.5 3 6 12 24 48
101 0.8125 1.625 3.25 6.5 13 26 52
110 0.875 1.75 3.5 7 14 28 56
111 0.9375 1.875 3.75 7.5 15 30 60
请注意,随着我们向更大的值移动,可表示值之间的差距会变得更大。我们可以表示0.5 和1.0 之间的8 个值,每个值之间有0.0625 的间隔。我们可以表示1.0 和2.0 之间的8 个值,每个值之间有0.125 的间隔。我们可以表示2.0 和4.0 之间的8 个值,每个值之间有0.25 的间隔。等等。请注意,我们可以表示直到16 的所有正整数,但我们不能用这种格式表示值17;我们只是在有效数字中没有足够的位来这样做。如果我们以这种格式添加值8 和9,我们将得到16,这是一个舍入错误。如果该结果用于任何其他计算,则该舍入误差将被复合。
请注意,无论有效数字中有多少位,都无法准确表示某些值。就像1/3 给我们非终止小数0.333333...,1/10 给我们非终止二进制小数1.10011001100...。我们需要在有效数字中使用无限多的位来表示该值。
【讨论】:
64 位机器上的双精度数,有一个符号位、11 个指数位和 52 个小数位。
想想(1 个符号位)*(52 个小数位)^(11 个指数位)
【讨论】: