进制转换
定义
一个 进制数(, 为整数)把数值写成数码串,每一位的数码取自 ,数码所在的位置决定它的位权。若整数部分有 位、小数部分有 位,则
第 位的位权是 :小数点左边从最低位起依次为 ,小数点右边依次为 。最高位记作MSB,最低位记作LSB。
下标 标注底数,十进制常省略下标。不写下标时,同一串数码可能对应不同的值:
| 进制 | 底数 | 可用数码 |
|---|---|---|
| 二进制 | ||
| 八进制 | ||
| 十进制 | ||
| 十六进制 | , 分别表示 |
性质
位权与移位
相邻两位的位权之比等于底数 。对整数表示来说,在末尾补一个 ,数值乘以 ;删去末尾的一个 ,数值除以 。二进制整数左移一位就是乘 ,右移一位就是除以 取整。
整数部分与小数部分分别处理
按权展开式中,整数部分只出现非负幂,小数部分只出现负幂,两者互不影响。所以含小数点的数可以整数、小数分别转换,再按小数点位置拼接。
以 的幂为底的进制
若 ,则每一位 进制数码恰好对应 位二进制数。因为 、,二进制与八进制、十六进制可以按 位或 位分组直接互转。这种逐位对应只存在于底数为 的幂的进制之间,十进制与八进制、十六进制之间没有。
转换方法
进制转十进制
按位权展开,把每一位的数码乘以该位的位权后相加。整数部分用正幂,小数部分用负幂。
十进制整数转 进制
-
除以 ,记下余数
用当前整数除以 ,余数就是当前最低位的数码。
-
用商继续
把商作为新的整数,重复上一步,直到商为 。
-
逆序读取余数
最先得到的余数是最低位,最后得到的是最高位,从下往上读。
十进制小数转 进制
-
乘以
用当前小数部分乘以 。
-
取出整数部分
乘积的整数部分是当前小数位的数码,剩下的小数部分进入下一轮。十六进制中整数部分 要写成 。
-
重复到终止
直到小数部分变为 ,或达到所需精度。取出的数码按先后顺序从左到右写出。
二进制与八进制、十六进制互转
以小数点为界,整数部分向左、小数部分向右分组:八进制每 位一组,十六进制每 位一组,每组换成对应的 位八进制或十六进制数码。反方向转换时,把每一位八进制数码写成 位二进制数、每一位十六进制数码写成 位二进制数,再以小数点为界拼接,去掉整数部分的前导 和小数部分的末尾 。
八进制与十六进制的小数同样按位权展开,权分别为 与 。它们与十进制小数互转时,通常先换成二进制,再用分组法处理。
数位对应表
| 十进制 | 二进制 | 八进制 | 十六进制 |
|---|---|---|---|
| 0 | 0000 | 0 | 0 |
| 1 | 0001 | 1 | 1 |
| 2 | 0010 | 2 | 2 |
| 3 | 0011 | 3 | 3 |
| 4 | 0100 | 4 | 4 |
| 5 | 0101 | 5 | 5 |
| 6 | 0110 | 6 | 6 |
| 7 | 0111 | 7 | 7 |
| 8 | 1000 | 10 | 8 |
| 9 | 1001 | 11 | 9 |
| 10 | 1010 | 12 | A |
| 11 | 1011 | 13 | B |
| 12 | 1100 | 14 | C |
| 13 | 1101 | 15 | D |
| 14 | 1110 | 16 | E |
| 15 | 1111 | 17 | F |
例子
把 转换为十进制
把 转换为二进制
用 反复除以 ,记录余数:
从下往上读余数,得到 。
把 转换为二进制
整数部分与小数部分分别转换,再拼接。
-
整数部分 :按除 取余,。
-
小数部分 :
- ,取整 ,剩 ;
- ,取整 ,剩 ;
- ,取整 ,剩 ,结束。
按取出的顺序排列,。
最终结果:。
把 转换为十进制
把 转换为八进制
以小数点为界,向左每 位一组:
把 转换为十六进制
以小数点为界,向左每 位一组:
编程实现
下面的两个程序分别实现二进制转十进制和十进制整数转二进制。它们把上面的步骤写成循环:前者用不断折半的位权代替重复的指数运算,后者把余数插到列表头部来完成逆序。
二进制转十进制
b = input("Please enter a binary number:")d = 0weight = 2 ** (len(b) - 1)for i in range(0, len(b)): if b[i] == "1": d = d + weight weight = weight // 2 # ‘//’是整数除法print(d)如果每轮都在循环里重新计算 ,会多做大量乘法。改进后的写法只在循环外算一次最高位权 ,之后用整数除法把位权逐位折半,和按权展开的结果一致。注意只有数码为1的位需要累加。
十进制整数转二进制
x = int(input("Please enter a decimal number:"))r = 0Rs = []while x != 0: r = x % 2 x = x // 2 Rs = [r] + Rsfor i in range(0, len(Rs)): # 从最高位到最低位依次输出;Rs[0] 是最高位。 print(Rs[i], end="")x % 2依次给出从低到高的各位,Rs = [r] + Rs把新余数放到列表头部,因此最后从Rs[0] 开始输出就是高位到低位,不需要再反转列表。
交互探索
选择整数和进制,比较数位、位权与表示结果。
同一个整数怎样用不同进制表示?
改变整数和进制,查看各数位及其位权。
正在准备演示…
练习
的十进制值是 。
参考解答
。
十进制数 的二进制表示是 (只填数码,不写下标)。
参考解答
,所以是 。
八进制数 的十进制值是 。
参考解答
。
把 写成十六进制,结果是:
参考解答
每 位一组:,,所以是 。
下列关于进制转换的说法,正确的是:
参考解答
的二进制展开无限循环;除 取余时最先得到的是最低位;小数部分应在右端补 。