跳转到内容

2. 不同进制之间的换算

在十进制中,个位的 1 代表 100 = 1,十位的 1 代表 101=10,百位的 1 代表 102 = 100,所以

123 = 1 × 102 + 2 × 101 + 3 × 100

同样道理,在二进制中,个位的 1 代表 20 = 1,十位的 1 代表 21 = 2,百位的 1 代表 22 = 4,所以

(A3A2A1A0)2 = A × 2 + A × 2 + A × 2 + A0 × 20

如果二进制和十进制数出现在同一个等式中,为了区别我们用 (A3A2A1A0)2这种形式表示 A3A2A1A0是二进制数,每个数字只能是 0 或 1,其它没有套括号加下标的数仍表示十进制数。对于 (A3A2A1A0)2这样一个二进制数,最左边的 A3位称为最高位(MSB,Most Significant Bit),最右边的 A0位称为最低位(LSB,Least Significant Bit)。以后我们遵循这样的惯例:LSB 称为第 0 位而不是第 1 位,所以如果一个数是 32 位的,则 MSB 是第 31 位。上式就是从二进制到十进制的换算公式。作为练习,请读者算一下 (1011)2和 (1111)2换算成十进制分别是多少。

下面来看十进制怎么换算成二进制。我们知道

13 = 1 × 23 + 1 × 22 + 0 × 21 + 1 × 20

所以 13 换算成二进制应该是 (1101)2。问题是怎么把 13 分解成等号右边的形式呢?注意到等号右边可以写成

13 = ((((0 × 2 + 13) × 2 + 12) × 2 + 01) × 2 + 10

我们将 13 反复除以 2 取余数就可以提取出上式中的 1101 四个数字,为了让读者更容易看清楚是哪个 1 和哪个 0,上式和下式中对应的数字都加了下标:

13 ÷ 2 = 6...10 6 ÷ 2 = 3...01 3 ÷ 2 = 1...12 1 ÷ 2 = 0...13

把这四步得到的余数按相反的顺序排列就是 13 的二进制表示,因此这种方法称为除二反序取余法。

计算机用二进制表示数,程序员也必须习惯使用二进制,但二进制写起来太啰嗦了,所以通常将二进制数分成每三位一组或者每四位一组,每组用一个数字表示。比如把 (10110010)2从最低位开始每三位分成一组,10、110、010,然后把每组写成一个十进制数字,就是 (262)8,这样每一位数字的取值范围是 0~7,逢八进一,称为八进制(Octal)。类似地,把 (10110010)2分成每四位一组,1011、0010,然后把每组写成一个数字,这个数的低位是 2,高位已经大于 9 了,我们规定用字母 A~F 表示 10~15,这个数可以写成 (B2)16,每一位数字的取值范围是 0~F,逢十六进一,称为十六进制(Hexadecimal)。所以,八进制和十六进制是程序员为了书写二进制方便而发明的简便写法,好比草书和正楷的关系一样。

习题

  1. 二进制小数可以这样定义:

    (0.A1A2A3...)2 = A1 × 2-1 + A2 × 2-2 + A3 × 2-3+...

    这个定义同时也是从二进制小数到十进制小数的换算公式。从本节讲的十进制转二进制的推导过程出发类比一下,十进制小数换算成二进制小数应该怎么算?

  2. 再类比一下,八进制(或十六进制)与十进制之间如何相互换算?