当十进制小数可以表示为形如 (1/2+1/4+1/8+…) 的分数之和时,发现与之对应的二进制实数就非常容易了。如下表所示,左列中的大多数分数不容易转换为二进制。不过,可以将它们写成第二列的形式。
十进制分数 | 分解为… | 二进制实数 | 十进制分数 | 分解为… | 二进制实数 |
---|---|---|---|---|---|
1/2 | 1/2 | .1 | 3/8 | 1/4+1/8 | .011 |
1/4 | 1/4 | .01 | 1/16 | 1/16 | .0001 |
3/4 | 1/2+1/4 | .11 | 3/16 | 1/8+1/16 | .0011 |
1/8 | 1/8 | .001 | 5/16 | 1/4+1/16 | .0101 |
7/8 | 1/2+1/4+1/8 | .111 |
很多实数,如 1/10(0.1)或 1/100(0.01),不能表示为有限位的二进制数,它们只能近似地表示为一组以 2 的幂为分母的分数之和。想想看,像 $39.95 这样的货币值受到了怎样的影响!
当十进制数比较小的时候,将十进制分数转换为二进制的一个简单方法就是:先将分子与分母转换为二进制,再执行长除。例如,十进制数 0.5 表示为分数就是 5/10,那么十进制 5 等于二进制 0101,十进制 10 等于二进制 1010。执行了长除之后,商为二进制数 0.1:
当被除数减去除数 1010 的结果为 0 时,除法完成。因此,十进制分数 5/10 等于二进制数 0.1。这种方法被称为二进制长除法(binary long division method)。
下面用二进制长除法将十进制数 0.2(2/10)转换为二进制数。首先,用二进制 10 除以二进制 1010(十进制 10):
第一个足够大到能上商的数是 10000。从 10000 减去 1010 后,余数为 110。添加一个 0 后,形成新的被除数 1100。从 1100 减去 1010 后,余数为 10。添加三个 0 后,形成新的被除数 10000。
这个数与第一个被除数相同。从这里开始,商的位序列出现重复(0011...),由此可知,不会得到确定的商,所以,0.2 也不能表示为有限位的数。其单精度编码的有效数字为 10011001100110011001100。
IEEE 单精度数转换为十进制时,建议步骤如下:
1) 若 MSB 为 1,该数为负;否则,该数为正。
2) 其后 8 位为阶码。从中减去二进制值 01111111(十进制数 127),生成无偏差阶码。将无偏差阶码转换为十进制。
3) 其后 23 位表示有效数字。添加“1.”,后面紧跟有效数字位,尾随零可以忽略。用形成的有效数字、第一步得到的符号和第二步计算出来的阶码,就构成一个二进制浮点数。
4) 对第三步生成的二进制数进行非规格化。(按照阶码的值移动二进制小数点。如果阶码为正,则右移;如果阶码为负,则左移。)
5) 利用加权位计数法,从左到右,将二进制浮点数转换为 2 的幂之和,形成十进制数。
【示例】IEEE(0 10000010 01011000000000000000000)转换为十进制
1) 该数为正数。
2) 无偏差阶码的二进制值为 00000011,十进制值为 3。
3) 将符号、阶码和有效数字组合起来即得该二进制数为 +1.01011 x2³。
4) 非规格化二进制数为 +1010.11。
5) 则该数的十进制值为 +10 3/4,或 +10.75。