# 2.4.3 数字示例

图 2-34 展示了一组数值,它们可以用假定的 6 位格式来表示,有 k = 3 的阶码位和 n = 2 的尾数位。偏置量是 23-1 - 1 = 3。图中的 a 部分显示了所有可表示的值(除了 NaN)。两个无穷值在两个末端。最大数值的规格化数是 ±14。非规格化数聚集在 0 的附近。图的 b 部分中,我们只展示了介于 -1.0 和 +1.0 之间的数值,这样就能够看得更加清楚。两个零是特殊的非规格化数。可以观察到,那些可表示的数并不是均匀分布的,越靠近原点处它们越稠密。

图 2-34 6 位浮点格式可表示的值

图 2-35 展示了假定的 8 位浮点格式的示例,其中有 k = 4 的阶码位和 n = 3 的小数位。偏置量是 24-1 - 1 = 7。图被分成了 3 个区域,来描述 3 类数字。不同的列给出了阶码字段是如何编码阶码 E 的,小数字段是如何编码尾数 M 的,以及它们一起是如何形成要表示的值 V = 2E × M 的。

从 0 自身开始,最靠近 0 的是非规格化数。这种格式的非规格化数的 E = 1 - 7 = -6,得到权 2E = 1/64。小数 f 的值的范围是 0, 1/8, ..., 7/8,从而得到数 V 的范围是 0 ~ 1/64 × 7/8 = 7/512。

图 2-35 8 位浮点格式的非负值示例

这种形式的最小规格化数同样有 E = 1 - 7 = -6,并且小数取值范围也为 0, 1/8, ..., 7/8。然而,尾数在范围 1 + 0 = 1 和 1 + 7/8 = 15/8 之间,得出数 V 在范围 8/512 = 1/64 和 15/512 之间。可以观察到最大非规格化数和最小规格化数之间的平滑转变。这种平滑性归功于我们对非规格化数的 E 的定义。通过将 E 定义为 1 - Bias,而不是 -Bias,我们可以补偿非规格化数的尾数没有隐含的开头的 1。

当增大阶码时,我们成功地得到更大的规格化值,通过 1.0 后得到最大的规格化数。这个数具有阶码 E = 7,得到一个权 2E = 128。小数等于 7/8,得到尾数 M = 15/8。因此,数值是 V = 240。超出这个值就会溢出到 +∞。

这种表示具有一个有趣的属性:假如我们将图 2-35 中的值的位表达式解释为无符号整数,它们就是按升序排列的,就像它们表示的浮点数一样。这不是偶然的,IEEE 格式如此设计就是为了浮点数能够使用整数排序函数来进行排序。当处理负数时,有一个小的难点,因为它们有开头的 1,并且它们是按照降序出现的,但是不需要浮点运算来进行比较也能解决这个问题(参见家庭作业 2.84)。

练习题 2.47 假设一个基于 IEEE 浮点格式的 5 位浮点表示,有 1 个符号位、2 个阶码位(k = 2)和两个小数位(n = 2)。阶码偏置量是 22-1 - 1 = 1。

下表中列举了这个 5 位浮点表示的全部非负取值范围。使用下面的条件,填写表格中的空白项:

e:假定阶码字段是一个无符号整数所表示的值。

E:偏置之后的阶码值。

2E:阶码的权重。

f:小数值。

M:尾数的值。

2E × M:该数(未归约的)小数值。

V:该数归约后的小数值。

十进制:该数的十进制表示。

写出 2E、f、M、2E × M 和 V 的值,要么是整数(如果可能的话),要么是形如 x/y 的小数,这里 y 是 2 的幂。标注为 “-” 的条目不用填。

e E 2E f M 2E × M V 十进制
0 00 00
0 00 01
0 00 10
0 00 11
0 01 00
0 01 01 1 0 1 1/4 5/4 5/4 5/4 1.25
0 01 10
0 01 11
0 10 00
0 10 01
0 10 10
0 10 11
0 11 00 - - - - - - -
0 11 01 - - - - - - -
0 11 10 - - - - - - -
0 11 11 - - - - - - -

图 2-36 展示了一些重要的单精度和双精度浮点数的表示和数字值。根据图 2-35 中展示的 8 位格式,我们能够看出有 k 位阶码和 n 位小数的浮点表示的一般属性。

描述 exp frac 单精度:值 单精度:十进制 双精度:值 双精度:十进制
0 00...00 0...00 0 0.0 0 0.0
最小非规格化数 00...00 0...01 2-23 × 2-126 1.4 × 10-45 2-52 × 2-1022 4.9 × 10-324
最大非规格化数 00...00 1...11 (1 - ε) × 2-126 1.2 × 10-38 (1 - ε) × 2-1022 2.2 × 10-308
最小规格化数 00...01 0...00 1 × 2-126 1.2 × 10-38 1 × 2-1022 2.2 × 10-308
1 01...11 0...00 1 × 20 1.0 1 × 20 1.0
最大规格化数 11...10 1...11 (2 - ε) × 2127 3.4 × 1038 (2 - ε) × 21023 1.8 × 10308

图 2-36 非负浮点数的示例

  • 值 +0.0 总有一个全为 0 的位表示。
  • 最小的正非规格化值的位表示,是由最低有效位为 1 而其他所有位为 0 构成的。它具有小数(和尾数)值 M = f = 2-n,阶码值 E = -2k-1 + 2。因此它的数字值是 V = 2^(-n - 2^(k-1) + 2)。
  • 最大的非规格化值的位模式是由全为 0 的阶码字段和全为 1 的小数字段组成的。它有小数(和尾数)值 M = f = 1 - 2-n(我们写成 1 - ε),阶码值 E = -2k-1 + 2。因此,数值 V = (1 - 2-n) × 2^(-2^(k-1) + 2),这仅比最小的规格化值小一点。
  • 最小的正规格化值的位模式的阶码字段的最低有效位为 1,其他位全为 0。它的尾数值 M = 1,而阶码值 E = -2k-1 + 2。因此,数值 V = 2^(-2^(k-1) + 2)。
  • 值 1.0 的位表示的阶码字段除了最高有效位等于 1 以外,其他位都等于 0。它的尾数值是 M = 1,而它的阶码值是 E = 0。
  • 最大的规格化值的位表示的符号位为 0,阶码的最低有效位等于 0,其他位等于 1。它的小数值 f = 1 - 2-n,尾数 M = 2 - 2-n(我们写作 2 - ε)。它的阶码值 E = 2k-1 - 1,得到数值 V = (2 - 2-n) × 2^(2^(k-1) - 1) = (1 - 2-n-1) × 2^(2^(k-1))。

练习把一些整数值转换成浮点形式对理解浮点表示很有用。例如,在图 2-15 中我们看到 12 345 具有二进制表示 [11000000111001]。通过将二进制小数点左移 13 位,我们创建这个数的一个规格化表示,得到 12345 = 1.10000001110012 × 213。为了用 IEEE 单精度形式来编码,我们丢弃开头的 1,并且在末尾增加 10 个 0,来构造小数字段,得到二进制表示 [10000001110010000000000]。为了构造阶码字段,我们用 13 加上偏置值 127,得到 140,其二进制表示为 [10001100]。加上符号位 0,我们就得到二进制的浮点表示 [01000110010000001110010000000000]。

回想一下 2.1.3 节,我们观察到整数值 12 345(0x3039)和单精度浮点值 12345.0(0x4640E400)在位级表示上有下列关系:

整数 12345 与单精度浮点数 12345.0 的位对齐关系

现在我们可以看到,相关的区域对应于整数的低位,刚好在等于 1 的最高有效位之前停止(这个位就是隐含的开头的位 1),和浮点表示的小数部分的高位是相匹配的。

练习题 2.48 正如在练习题 2.6 中提到的,整数 3 510 593 的十六进制表示为 0x00359141,而单精度浮点数 3510593.0 的十六进制表示为 0x4A564504。推导出这个浮点表示,并解释整数和浮点数表示的位之间的关系。

练习题 2.49

A. 对于一种具有 n 位小数的浮点格式,给出不能准确描述的最小正整数的公式(因为要想准确表示它需要 n + 1 位小数)。假设阶码字段长度 k 足够大,可以表示的阶码范围不会限制这个问题。

B. 对于单精度格式(n = 23),这个整数的数字值是多少?