教孩子学编程(信息学奥赛C语言版)
上QQ阅读APP看书,第一时间看更新

1.7 数制转换

我们在小学算术中学过,十进制数的个位(从右向左第1位)上的1表示数值1,十位(从右向左第2位)上的1表示数值10,百位(从右向左第3位)上的1表示数值100,千位(从右向左第4位)上的1表示数值1000,依此类推,从右向左第n位上的1表示的数值是10n-1。我们把一个数从右向左第n位上的1所表示的数值大小称为该数位上的位权。表1.5列出了十进制数、二进制数、八进制数和十六进制数各个数位上的位权大小。

表1.5 各个数位上的位权

一个十进制数所表示的数值大小就等于各个数位上的位权乘以该数位上的值(0~9)再相加得到的总和。例如:

9504=1000×9+100×5+10×0+1×4

二进制数也是同样的原理。二进制数从右向左第1位上的1表示数值1(20),第2位上的1表示数值2(21),第3位上的1表示数值4(22),第4位上的1表示数值8(23),依此类推,从右向左第n位上的1表示的数值是2n-1

二进制数各位的位权与各位上的值(0或1)的乘积的总和就是这个二进制数所对应的十进制数(见图1.10)。例如把二进制数101011转换为十进制数就是:

25×1+24×0+23×1+22×0+21×1+20×1=32+0+8+0+2+1=43

同理,八进制数各位的位权(8n-1)与各位上的值(0~7)的乘积的总和就是这个八进制数所对应的十进制数(见图1.11)。例如把八进制数1753转换为十进制数就是:

83×1+82×7+81×5+80×3=512+448+40+3=1003

图1.10 二进制数转换为十进制数(位权2n-1的利用)

图1.11 八进制数转换为十进制数(位权8n-1的利用)

十六进制数各位的位权(16n-1)与各位上的值(0~F)的乘积的总和就是这个十六进制数所对应的十进制数(见图1.12)。例如把十六进制数27DB转换为十进制数就是:

163×2+162×7+161×13+160×11=8192+1792+208+11=10203

图1.12 十六进制数转换为十进制数(位权16n-1的利用)

利用二进制数各位的位权,可以把一个二进制数转换为十进制数,那么如果要知道十进制数所对应的二进制数是多少,该怎么办呢?

我们通常使用辗转相除求余法来得到一个十进制数所对应的二进制数,具体的操作步骤如下:用2去除十进制数,得到商和余数,这个余数就是对应的二进制数从右向左第1位的值;然后把商作为被除数继续用2去除,又得到一个商和余数,此时的余数就是对应的二进制数从右向左第2位的值;再次把得到的第二个商作为被除数继续用2除,得到第三个商和余数,这时的余数就是对应的二进制数从右向左第3位的值;像这样把每次得到的商作为被除数用2除,获取余数,直到商为0。最后把得到的所有余数从右向左依次排列就是这个十进制数对应的二进制数(见图1.13)。

知识点总结

在二进制数中,从右向左第n位拥有2n-1(2的n-1次方)的“位权”。

在八进制数中,从右向左第n位拥有8n-1(8的n-1次方)的“位权”。

在十六进制数中,从右向左第n位拥有16n-1(16的n-1次方)的“位权”。

各位的位权与各位上的值的乘积的总和就是这个数所对应的十进制数。

图1.13 把十进制数转换为二进制数的步骤

同样的原理,用8作为除数对一个十进制数进行辗转相除,把得到的所有余数从右向左依次排列,可以得到这个十进制数对应的八进制数(见图1.14)。

图1.14 把十进制数转换为八进制数的步骤

用16作为除数对一个十进制数进行辗转相除,把得到的所有余数从右向左依次排列,可以得到这个十进制数对应的十六进制数(见图1.15)。

图1.15 把十进制数转换为十六进制数的步骤

当把二进制数转换为八进制数或十六进制数时,可以先把二进制数转换为十进制数,然后再把这个十进制数转换为八进制数或十六进制数;反过来,八进制数或十六进制数转换为二进制数时,则先把它转化为十进制数,再把这个十进制数转换为二进制数;八进制数与十六进制数之间的相互转换也是如此。除此之外,我们也可以利用前面讲过的各个数位上的位权,把二进制数直接转换为八进制数或十六进制数。要进行这种直接转换需要了解二进制数与八进制数、十六进制数之间的特殊关系。

知识点总结

用2除十进制数时得到的余数就是十进制数所对应的二进制数各位的值。

用8除十进制数时得到的余数就是十进制数所对应的八进制数各位的值。

用16除十进制数时得到的余数就是十进制数所对应的十六进制数各位的值。

八进制数的各位可以取0~7这几个值,这正好是用3位二进制数(000~111)能表示的值(见表1.6);十六进制数的各位可以取0~F这几个值,这正好是用4位二进制数(0000~1111)能表示的值(见表1.7)。因此我们可以总结出下面的特殊关系:

·二进制数的3位相当于八进制数的1位;

·二进制数的4位相当于十六进制数的1位。

表1.6 二进制数与八进制数对应表

表1.7 二进制数与十六进制数对应表

所以当把二进制数转换为八进制数时,可以从低位起(从右向左)把二进制数划分为每3位一个区间,再把每个区间内的3位二进制数转换为对应的十进制数,这样最终得到的数就是这个二进制数对应的八进制数。当把二进制数转换为十六进制数时,可以从低位起(从右向左)把二进制数划分为每4位一个区间,再把每个区间内的4位二进制数转换为对应的十进制数(10~15用A~F表示),这样最终得到的数就是这个二进制数对应的十六进制数(见图1.16)。

反过来,把八进制数转换为二进制数时,将八进制数的各位变换为3位二进制数,就得到了这个八进制数对应的二进制数;把十六进制数转换为二进制数时,将十六进制数的各位变换为4位二进制数,就得到了这个十六进制数对应的二进制数(见图1.17)。

知识点总结

3位二进制数的值正好能用1位八进制数来表示。

4位二进制数的值正好能用1位十六进制数来表示。

在C语言中如果一个数以0x开头,表示这是一个十六进制数。比如0x45表示45是一个十六进制数。

在C语言中如果一个数以0开头,表示这是一个八进制数。比如025表示25是一个八进制数。

图1.16 把二进制数转换为八进制数、十六进制数的步骤

图1.17 把八进制数、十六进制数转换为二进制数的步骤