所谓进制转换,就是将一种进制的数字转换为另一种进制的数字。数字的表示形式虽然改变了,但是数字的值并没有变。
这里我们讲解两种方法,第一种是简单的口算法,第二种是复杂的公式法。
进制转换口算法
我们来思考一个问题:为什么八进制数 17 对应的十进制数是 15?我们看八进制数 17 中的 7,这个 7 是没有进位的,它同十进制数 7 是一样的,因为它是在个位。而八进制数 17 中的 1,它能进一是因为有 8 才进一的,所以这个 1 代表的就是十进制的 8。所以一个 8 和一个 7 加起来就是 15,这就是为什么八进制数 17 对应的十进制数是 15 的原因。
现在我来考考读者,看读者能不能立刻回答出来。八进制数 23 对应的十进制数是多少?十进制数 34 对应的八进制数是多少?
同样,八进制数 23 中的 3 和十进制数 3 是一样的,而 2 说明进了两次位,有 8 才能进一次,进了两次说明是十进制的 16,所以 16 和 3 加起来就是 19。因此八进制数 23 对应的就是十进制数 19。
十进制数 34 里有 4 个 8,余 2,所以十进制数 34 对应的就是八进制的 42。
我再来问问大家,看大家能不能举一反三:十六进制的 3D 对应的十进制是多少?十进制的 83 对应的十六进制是多少?
方法是相同的,十六进制数 3D 中的 D 表示的是十进制的 13,而十六进制达到 16 才能进一次,数字 3 说明进了 3 次,即 48,13 和 48 加起来就是 61。因此,十六进制数 3D 就对应十进制数 61。同样,十进制 83 中有 5 个 16,余 3,所以十进制数 83 就是十六进制数 53。
如果是八进制和十六进制相互转换的话,因为它们都跟十进制有关系,所以可以将十进制当作一个桥梁,先转换成十进制,然后再转换成另一个进制。
以上的口算方法实际上就是进制转换的本质和奥秘的总结。但是用口算方法只能计算比较小的数字,当数字比较大的时候还是得在纸上算。之所以没有讲如何用口算进行二进制转换,原因就是二进制的计算量很大,不适合口算。介绍口算方法的主要目的是想让大家体会进制转换的本质,从而能够深刻理解下面所讲的公式法。
进制转换公式法
以上讲的是进制转换的本质,下面系统地讲一下进制转换。在阅读本节之前建议大家先掌握上节的内容,这样效率会更高,理解会更深刻。
1) r 进制转换成十进制
r 进制数 a
n a
n–1…a
1 a
0 对应的十进制数为:
an×rn + an–1×rn–1 + … + a1×r1 + a0×r0
下面给大家举几个例子:
-
(1011011)2=1×26+0×25+1×24+1×23+0×22+1×21+1×20=64+0+16+8+0+2+1=91
-
(356)8=3×82+5×81+6×80=192+40+6=238
-
(2FB)16=2×162+15×161+11×160=512+240+11=763
2) 十进制转换成 r 进制
方法:除 r 取余数,直至商为零,余数倒序排序。
下面给大家举个例子:十进制 185 分别转换成二进制、八进制和十六进制。
所以(185)
10=(10111001)
2。
所以(185)
10=(271)
8。
(185)
10=(B9)
16。
3) 进制之间的转换
上面讲了十进制和r进制之间的相互转换。可以说十进制是任意进制间相互转换的桥梁,任何进制都可以先转换成十进制,然后再转换成需要的进制。
但二进制和八进制、二进制和十六进制之间的相互转换可以直接计算。二进制的运算首先要记住窍门:8421。(1111)
2=1×2
3+1×2
2+1×2
1+1×2
0=8+4+2+1,即二进制数 1111 从左到右每一位分别代表十进制的 8、4、2、1。
① 二进制转换为八进制
将二进制数从右到左,每三位组成一组,最左边不足三位的补零。然后对每组分别运用 8421 法则快速运算。如果二进制是 1 则保留,如果是 0 则舍去。比如:
-
(1111)2=8+4+2+1=15
-
(1010)2=8+0+2+0=10
-
(1100)2=8+4+0+0=12
-
(0101)2=0+4+0+1=5
所有的二进制转其他进制的运算都要记住这个法则。如果是二进制转十进制,且二进制数多于四位,那么其他位依次为 16、32、64、128……
只不过二进制转八进制时,因为是每三位为一组,所以就不存在第四位,这样 8 就都为 0 了,所以其实是 421 法则,但统一记为“8421”更顺口。
【练习】(11001011)
2=(?)
8
首先,从右到左分成三组,最左边不足三位的补零,即 011001011。然后对每组分别运用“8421”快速运算即 313。所以(11001011)
2=(313)
8。
② 二进制转换为十六进制
将二进制数从右到左,每四位组成一组,最左边不足四位的补零。然后对每组分别运用“8421”法则快速运算。
【练习】(1011001011)
2=(?)
16
首先,从右到左分成四组,最左边不足四位的补零,即 001011001011。然后对每组分别运用“8421”法则快速运算即 2 C B。所以(11001011)
2=(2CB)
16。
③ 八进制转换为二进制
对于每一位八进制数,分别运用“8421”法则快速运算,逐位展开成三位二进制数,不足三位的补零,最后最左边的零可省略。
【练习】(3754)
8=(?)
2
(3)
8=(011)
2,(7)
8=(111)
2,(5)
8=(101)
2,(4)
8=(100)
2,所以(3754)
8=(11111101100)
2。
④ 十六进制转换为二进制
对于每一位十六进制数,分别运用“8421”法则快速运算,逐位展开成四位二进制数,不足四位的补零,最后最左边的零可省略。
【练习】(4B39F)
16=(?)
2
(4)
16=(0100)
2,(B)
16=(1011)
2,(3)
16=(0011)
2,(9)
16=(1001)
2,(F)
16=(1111)
2,所以(4B39F)
16=(1001011001110011111)
2。
最后还有一个“小数部分的进制转换”,这个几乎用不到,所以就不讲了,要是以后用到了再看也不迟。
接下来给大家写一个程序。这个程序的功能是将同一个十进制数以不同的进制显示出来。这个程序大家暂时还看不懂,没关系,等学到后面再来看这个程序就很简单了。
#include <stdio.h>
int main(void){
int i = 63;
printf("i = %d\n", i);
printf("i = %o\n", i);
printf("i = %x\n", i);
printf("i = %X\n", i);
return 0;
}
运行结果:
i = 63
i = 77
i = 3f
i = 3F
其中:
%d
表示以十进制输出;
%o
表示以八进制输出,注意是字母 o 不是数字 0,而且一定是小写字母。这与前面讲的八进制数是数字 0 而不是字母 o 正好是相反的,千万不要弄混了。
%x
和
%X
表示以十六进制输出。那么它们有什么区别呢?如果是 %x 那么字母就是以小写的形式输出,如果是 %X 那么字母就是以大写的形式输出。这也是八进制中只有 %o 没有 %O 的原因,因为八进制中根本没有字母,所以不需要区分大小写。