本文目录
【文章概要】
本文主要讲述的是二进制、十进制、十六进制三种数制的转换方法,以及其对应的编程实现。
一、进制的概念
首先讲讲数制的基和权,这是数制的基础。
基:基数,是组成该数制的数码个数,二进制的基数就是2,包含2个数字。
权:权值,指每一个数位上的1对应的数值,可表示为基数的若干次幂。
注:如对概念不清楚,可选择看下方二进制和十进制的图解示例。
进制的标识
用下标标识,十进制可以省略,如十进制(10)2、十进制10。
字母标识:二进制B、八进制O、十进制D、十六进制H。
★十进制、十六进制、二进制之间的关系(表)
十进制 | 十六进制 | 二进制 |
---|---|---|
0 | 0 | 0 |
1 | 1 | 1 |
2 | 2 | 10 |
3 | 3 | 11 |
4 | 4 | 100 |
5 | 5 | 101 |
6 | 6 | 110 |
7 | 7 | 111 |
8 | 8 | 1000 |
9 | 9 | 1001 |
10 | A | 1010 |
11 | B | 1011 |
12 | C | 1100 |
13 | D | 1101 |
14 | E | 1110 |
15 | F | 1111 |
规律:一般地,n进制逢n进一,能够出现的基本数码为:0~(n-1),不会出现n。注意,当数码大于9时,将用大写字母代替。例如:二进制的基本数码为0、1,不会出现2。
二、十进制转化为二进制、十六进制
十进制→二进制:采用“除2取余,至商为0,倒序输出”的方法。
【程序实现】
【思路】由此可知,我们只需要获取数据,然后计算其商、余数,然后逆序储存二进制数值。
【麒麟川伴你写代码】
第一步,我们先存储这一数据(这是一个整数,且不需要取里面的值,故不用字符串);
num = 56
第二步,准备两个变量,一个是储存余数的r(整数类型),一个是储存二进制数值的s,因为这一数值需要将余数倒序存入,故我们应当使用字符串类型储存;
r = 0 ; s = '' 确定一个变量的数据类型只要在变量中储存这一类型的数据即可。
第三步,因为我们需要一直计算其商、余数,故需要进行循环,但是我们无法确定次数,故需要使用while循环,对于其次数,我们用商是否为0来确定,而商的话恰好可以用原来的值的变换(具体变换见第五步)来实现,故我们给的条件是num不等于0;
while num != 0:
第四步,接下来进入循环体,首先我们取余数,然后再储存余数(注意是倒序);
r = num % 2 %为取余数的符号,意思是num除以2时余数的值
s = str(r) + s 由图知道,后面的数据应当放在前面,故r的值应当往前放,因为s是字符串,故r也需要通过str()函数变为字符串
第五步,我们需要把商求出来,让下一次循环使用这一数值,这一数值也用于第三步while的判断;
num = num // 2 整除即求商的方式,我们把num既当十进制值,也当商来用,和图上一致
第六步,退出循环体,输出二进制数值。
print(s)
总的代码:
num = 56
r = 0
s = ''
while num != 0:
r = num % 2
s = str(r) + s
num = num // 2
print(s)
十进制→十六进制:采用“除16取余,至商为0,倒序输出”的方法。
【程序实现】
【思路】由此可知,我们只需要获取数据,然后计算其商、余数,然后逆序储存十六进制数值。
【麒麟川伴你写代码】
第一步,我们先存储这一数据(这是一个整数,且不需要取里面的值,故不用字符串);
num = 60
第二步,准备两个变量,一个是储存余数的r(整数类型),一个是储存十六进制数值的s,因为这一数值需要将余数倒序存入,故我们应当使用字符串类型储存;
r = 0 ; s = '' 确定一个变量的数据类型只要在变量中储存这一类型的数据即可。
第三步,根据第一部分我们知道,十六进制的基本数码为0-9、A-F,所以超过10的数值应当转化为大写字母。这里由两种思路,一种是判断语句+ASCII值,一种是准备一个数据,储存这些数码,然后利用索引调用这些数码,因为这一中比较简单,故选用这一种(当然还有其他办法,本人想到了这两种);
sl = '0123456789ABCDEF'
第四步,因为我们需要一直计算其商、余数,故需要进行循环,但是我们无法确定次数,故需要使用while循环,对于其次数,我们用商是否为0来确定,而商的话恰好可以用原来的值的变换(具体变换见第五步)来实现,故我们给的条件是num不等于0;
while num != 0:
第五步,接下来进入循环体,首先我们取余数,然后再储存余数(注意是倒序);
r = num % 16 %为取余数的符号,意思是num除以16时余数的值
s = str(sl[r]) + s 因为余数的值是从0-15的,与sl这一序列的索引相同,故我们只需要用r当索引的序号,获取这一其对应的十六进制值。
第六步,我们需要把商求出来,让下一次循环使用这一数值,这一数值也用于第三步while的判断;
num = num // 16 整除即求商的方式,我们把num既当十进制值,也当商来用,和图上一致
第七步,退出循环体,输出十六进制数值。
print(s)
总的代码:
num = 60
r = 0 ; s = ''
sl = '0123456789ABCDEF'
while num != 0:
r = num % 16
s = str(sl[r]) + s
num = num // 16
print(s)
三、二进制转化为十进制、十六进制
二进制→十进制:采用“按权展开,逐项相加”的方法。
【程序实现】
【思路】由此可知,我们只需要获取数据的每一位的二进制数,并将其乘以对应的权值即可。
【麒麟川伴你写代码】
第一步,我们先存储这一数据(我们知道,想要获取单个数据,应当储存为字符串类型);
num = '110'
第二步,我们准备一个变量sum作为十进制的储存(因为十进制是计算求得的,故使用整数类型);
sum = 0
第三步,我们将依次获取每一个二进制数,不难想到,我们可以使用for遍历或for循环实现;
遍历法:for i in num: 此时i中依次储存的是1,1,0.
循环法[后续将用这一方法]:for i in range(len(num)): len(num)的作用是为了获取num的长度,i中依次为每个二进制数在num中的索引值,即0,1,2,后面调用该数值要用num[i].
第四步,现在进入循环体,以下代码均在循环体中进行。首先,我们来计算权值,不难看出,第一个数权值22的指数2可以用其长度减1代替,依次类推,设变量k为权值。
k = 2 ** (len(num)-1-i)
为什么是减1再减i呢?因为i的初始值为0,依次增大,而起始值是长度-1,后续在此基础上再依次相减
第五步,将其换算并加到sum中(这里的换算指的是二进制数*权值);
sum = sum + int(num[i]) * k 或写 sun += int(num[i]) * k 因为num是字符串,故里面的值也是字符,计算需要用int将其转换为整数类型
第六步,离开循环体,输出十进制数据,即储存的sum。
print(sum)
总的代码:
num = '110'
sum = 0
for i in range(len(num)):
k = 2 ** (len(num)-1-i)
sum += int(num[i]) * k
print(sum)
二进制→十六进制:采用“四位截取法”的方法。
四位截取法:二进制中的每四位数对应十六进制中的一位数。对二进制数进行分组,每四位分一组,每组对应着十六进制的一位数字。不足四位的,就在最高位前加“0”补足。
这一方法的程序实现可以参考下面的“十六进制转化为二进制”,原理相同。由于字数限制,故不作程序实现的解读,有需要或有意向了解请在公众号后台私信。
四、十六进制转化为二进制、十进制
十六进制→二进制:采用“四位截取法的逆向过程”的方法。
【程序实现】
【思路】由此可知,我们需要依次计算每位十六进制数值其所对应的二进制数值,再将其转化为二进制数值,并将其拼接起来。
【麒麟川伴你写代码】
第一步,我们先存储这一数据(我们知道十六进制含有字母,且我们需要取每一个值,应当储存为字符串类型);
num = 'A94'
第二步,创建两个变量,一个是十进制数值的储存,用整数即可,另一个用于储存二进制数值,因为最后要用于拼接,所以使用字符串类型;
t = 0 ; s = ''
第三步,因为我们要将十六进制转化为十进制,故十六进制的基本数码这一数据也需保留;
sl = '0123456789ABCDEF'
第四步,因为我们之后要讲十进制转化为二进制,所以我们定义一个函数tentotwo,其过程的讲解请看“十进制转换为二进制”这一目的内容;
def tentotwo(num):
r = 0; s = ''
while num != 0:
r = num % 2
s = str(r) + s
num = num // 2
return s 这一行是增加的,返回值s就是二进制的值(且是字符串),这样我们调用函数时这个函数显示的就是实际参数(十进制)所对应的二进制。
第五步,做好准备工作之后,现在我们来依次获取num中的每一个数值(这里使用遍历法);
for i in num: i中存储的就是num中的每一个数据:'A','9','4'
第六步,接下来进入循环体,这一步有些超纲,首先我们需要获取的十进制,而sl = '0123456789ABCDEF’的序列恰好对应了每一个十六进制数值的十进制数值,所以我们要获取i在sl中的索引序号是多少;
t= sl.index(i) sl.index(需要索引的值)就可以获取i在sl中的索引序号
第七步,我们将获得的十进制数值转化为二进制,然后存储到s变量中;
s += tentotwo(t)
第八步,退出循环体,输出二进制数值。
print(s)
总的代码:
num = 'A94'
t = 0 ; s = ''
sl = '0123456789ABCDEF'
def tentotwo(num):
r = 0; s = ''
while num != 0:
r = num % 2
s = str(r) + s
num = num // 2
return s
for i in num:
t= sl.index(i)
s += tentotwo(t)
print(s)
十六进制→十进制:采用“按权展开,逐项相加”的方法。
【程序实现】
【思路】由此可知,我们只需要获取数据的每一位的二进制数,并将其乘以对应的权值即可。
【麒麟川伴你写代码】
第一步,我们先存储这一数据(我们知道,想要获取单个数据,应当储存为字符串类型);
num = '23'
第二步,我们准备一个变量sum作为十进制的储存(因为十进制是计算求得的,故使用整数类型);
sum = 0
第三步,我们将依次获取每一个二进制数,不难想到,我们可以使用for遍历或for循环实现;
遍历法:for i in num: 此时i中依次储存的是1,7.
循环法[后续将用这一方法]:for i in range(len(num)): len(num)的作用是为了获取num的长度,i中依次为每个二进制数在num中的索引值,即0,1,后面调用该数值要用num[i].
第四步,现在进入循环体,以下代码均在循环体中进行。首先,我们来计算权值,不难看出,第一个数权值161的指数2可以用其长度减1代替,依次类推,设变量k为权值。
k = 16 ** (len(num)-1-i)
为什么是减1再减i呢?因为i的初始值为0,依次增大,而起始值是长度-1,后续在此基础上再依次相减
第五步,将其换算并加到sum中(这里的换算指的是二进制数*权值);
sum = sum + int(num[i]) * k 或写 sun += int(num[i]) * k 因为num是字符串,故里面的值也是字符,计算需要用int将其转换为整数类型
第六步,离开循环体,输出十进制数据,即储存的sum。
print(sum)
总的代码:
num = '23'
sum = 0
for i in range(len(num)):
k = 16 ** (len(num)-1-i)
sum += int(num[i]) * k
print(sum)
那么是减1再减i呢?因为i的初始值为0,依次增大,而起始值是长度-1,后续在此基础上再依次相减
第五步,将其换算并加到sum中(这里的换算指的是二进制数*权值);
sum = sum + int(num[i]) \* k 或写 sun += int(num[i]) \* k 因为num是字符串,故里面的值也是字符,计算需要用int将其转换为整数类型
第六步,离开循环体,输出十进制数据,即储存的sum。
print(sum)
总的代码:
num = '23'
sum = 0
for i in range(len(num)):
k = 16 ** (len(num)-1-i)
sum += int(num[i]) * k
print(sum)