导读
信息学能够有助于孩子未来工作发展,提升孩子的综合能力。
上一节课,我们讲解了进制的基本概念,这节课我们深入讲解进制的转换讲解编码相关知识。
这节课,我们来更加深入地讲解进制的相关内容。
1 常用进制
在C++中我们最常用的进制主要有:
二进制
八进制
十进制
十六进制
上一节课我们主要讲了进制的一些基本知识,这一节课,我们来了解一下进制的转化和运算。
2 十进制与其他进制的转换
有些孩子之前已经有学过十进制和其他进制的转换了。
十进制和其他进制之间的转换是比较简单的。
1、X进制转十进制
我们用X进制来统一表示非十进制,X进制转为十进制,其实就是将所有位置上的数字,按照其位置上的数据以及其位置做运算,然后得到十进制即可,这个可能比较不容易理解。我们举个例子:
123 = 1*10^2 + 2*10^1 + 3*10^0
其中:
10^2是指“10的2次方”,也就是2个10相乘,也就是100;
10^1是指“10的1次方”,也就是1个10相乘,也就是10;
10^0是指“10的0次方”,也就是1;(10^0 = 10^(1-1) = 10^1/10^1 = 1)
同理,二进制数据:
1011 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 (可以写为:2^3 + 2^1 + 2^0)
八进制数据:
01257 = 1*8^3 + 2*8^2 + 5*8^1 + 7*8^0
十六进制:
0xA1257 = 10*16^4 + 1*16^3 + 2*16^2 + 5*16^1 + 7*16^0
我们发现了对于X进制,就是满X进1。
将这些非十进制数字转换为十进制,就需要把这些数字先统一加起来,然后满十进一:
以八进制为例:
01257 = 1*8^3 + 2*8^2 + 5*8^1 + 7*8^0
= 512 + 128 + 40 + 7
= 687
所以八进制的01257就是十进制的687
我们再举个2进制的例子:
1011 = 2^3 + 2^1 + 2^0
= 8 + 2 + 1 = 11
掌握了这个方法,我们就可以把任意进制的数据转换为十进制了。
2、十进制转X进制
十进制转X进制,我们要做的就是除以X取余数,这个很好理解,因为我们X进制转十进制过程中,不满上一位,就会当做余数留在这一位,所以从十进制转过来,就是除以进制取余。
我们还是用前面的八进制转十进制的数值:
要注意,最后要一直运算到商为0为止,然后最上面的是最低位,最下面的是最高位。
其他的也是这样运算。我们要特别注意四位二进制数和十进制数之间的对应关系,最好能背下来,对以后学习很有帮助。
0000 = 0 | 1000 = 8 |
0001 = 1 | 1001 = 9 |
0010 = 2 | 1010 = 10 |
0011 = 3 | 1011 = 11 |
0100 = 4 | 1100 = 12 |
0101 = 5 | 1101 = 13 |
0110 = 6 | 1110 = 14 |
0111 = 7 | 1111 = 15 |
3、小数进制转换
十进制整数转换为X进制整数,是除以X取余,十进制小数转换为X进制小数,是乘以X取整(整数部分):
十进制3.25转二进制:
对于整数部分,3变为11;
对于小数部分0.25:
0.25*2 = 0.5 ,整数部分为0
0.5*2 = 1,整数部分是1
然后没有小数部分了,则二进制小数为0.01
那么最终的数就是11.01
想要X进制小数转换为十进制小数,就要用到负数次方,X进制的十分位就是X的-1次方,百分位X的-2次方。
对于11.01的小数部分:
0*2^(-1) + 1*2^(-2) = 0.25
3 二进制和八进制/十六进制的转换
除了上面的我们要着重说明的就是二进制和八进制/十六进制的转换了。
因为 用三位二进制数来表示一位八进制数。二进制和八进制的对应关系就是上面表中第一列的对应关系。
因为 ,所以我们可以用四位二进制数来表示一位十六进制数。二进制和十六进制的对应关系就是上面表中十六个数据的对应关系。
也就是说我们上面那个表熟练掌握之后,不仅能够快速对二进制和十进制之间相互转化,还能快速对二进制和八进制/十六进制之间进行转换。
转换过程中要考虑最高位是0的问题。如果最高几位是0,则运算完要省略。
例如:
十六进制数 0X1AB 转换为二进制:
1转换为:0001
A转换为:1010
B转换为:1011
所以转换为二进制就是:0001 1010 1011,
最后结果为:110101011
如果要转换回去,就从个位开始,四位一组,如果到了最前面不够四位,就用0补够四位:
然后我们转换为对应的十六进制数就可以了。
二进制和八进制数的转换的原理和二进制和十六进制的转换的原理是一样的,只不过要注意,用三位二进制数来表示一位八进制数。
举个例子:
八进制转二进制:0156 = 001 101 110 = 1101110
二进制转八进制:1010001 = 001 010 001 = 121 = 01
4 进制运算
最后我们要说一下进制的运算。主要考虑进制的加法和减法。
1、进制的加法
十进制就是满十进一。那对于X进制,就是满X进一。
我们通过几个例子来看一下:
【二进制】
1010 0011 + 1001 0001 = 1 0011 0100
【八进制】
01277 + 05652 = 07151
1、进制的减法
进制的减法就是进制加法的逆运算。在竞赛中有一类题目,就是告诉你一个加数和和,让你求另一个加数。
最简单的做法,就是用和减去加数,如果不够,就要借位。
2 编码
掌握了位运算的相关知识和有关于进制之间的相关操作,我们就可以来学习编码了!
1 原码反码补码及其转换
计算机如何实现两个整数的加减法呢?
计算机只能识别二进制,所以两个整数做运算,就是先转换为二进制再做运算。
例如我们想让计算机实现2+3,那么计算机就会这样做:
先把2和3都转换为二进制:
2:0000 0010
3:0000 0011
做完加法之后就是:0000 0101
这个数就是5。
如果我们想实现3-4,计算机会把减法转换为加法,也就是
先把3和-4都转换为二进制:
3:0000 0011
-4:1000 0100
做完加法之后就是:1000 0111
这个数就是-7。
也就是说,这样直接转换为二进制做运算是错误的!
计算机中,使用的是补码做数据的运算。我们先来看一下原码反码和补码!
把一个整数转换为对应的二进制数,这个二进制数就是这个整数的原码。
对于正整数来说,原码 = 反码 = 补码。
对于负整数来说,原码和反码的转换法则如下:
(除符号位外)各位求反
例如:
对于-4来说
【原码】1000 0100
【反码】1111 1011
原码和补码的转换规则为:
(除符号位外)各位求反,末位+1
例如:
对于-4来说,先各位求反,即求反码,再末位+1,即反码+1
【原码】1000 0100
【反码】1111 1011
【补码】1111 1100
从反码和补码转换为原码,我们从后面的应用来说明。
2 原补反应用
原补反的应用我们来看一下两个整数的加减法,我们以3和4为例,在计算机中做数据运算,是通过补码做运算的。
1、两个整数的加法
对于3+4,因为正数的原码 = 补码,所以运算如下:
1、先把3和4都转换为二进制原码:
3:0000 0011
4:0000 0100
2、转换为二进制补码(补码 = 原码):
3:0000 0011
4:0000 0100
3、做补码加法:
0000 0111
4、转换为对应原码(原码 = 补码):
0000 0111
5、原码转换为十进制数:7
2、两个整数的减法
对于3-4,要转换为 ,运算如下:
1、先把3和-4都转换为二进制原码:
3:0000 0011
-4:1000 0100
2、转换为二进制补码:
3:0000 0011
-4:1111 1100
3、做补码加法:
1111 1111
4、转换为对应原码(最高位是1,说明是负数):
1000 0000(先各位求反,即求反码)
1000 0001(再末位+1,即求原码)
5、原码转换为十进制数:-1
比较有趣的,是5-4:
1、先把5和-4都转换为二进制原码:
5:0000 0101
-4:1000 0100
2、转换为二进制补码:
5:0000 0101
-4:1111 1100
3、做补码加法(大家会发现这里有溢出,也就把数值变为正数了):
0000 0001
4、转换为对应原码:0000 0001
5、原码转换为十进制数:1
3、0的编码
最后一个要注意的是0,0有+0和-0:
+0的原码:0000 0000
-0的原码:1000 0000
转为反码和补码还是上面的原则:
+0(原码 = 反码 = 补码)
原码:0000 0000
反码:0000 0000
补码:0000 0000
-0
原码:1000 0000
反码:1111 1111
补码:0000 0000
我们发现0的原码和反码有不同的表示方法,但是,0的补码是唯一的!这也从另一个角度说明,整数的运算,只能用补码,不能原码和反码,如果使用原码和反码,0就不知道该如何参与运算了。
3 其他编码
1、ASCII编码
2、汉字编码
除此之外,还有汉字的编码。汉字编码使用的是双字节字符集(DBCS)。DBCS用2个字节定义1个字符,当2个字节编码值低于128时为ASCII码,编码值高于128时,为所在国家定义的编码。汉字早期采用双字节编码,字节最高位为0表示标准ASCII码;字节最高位为1时,用2个字节表示一个汉字。
但是上面的方法有一些缺点:
程序中处理字符串时,指针移动可能会导致错误;
字符串存储时,需要计算字符串的长度;
丢失双字节字符的高位字节后,会产生“乱码”现象;
在存储和传输中,是高字节在前,还是低字节在前?
现在使用的是1981年,《信息交换用汉字编码字符集·基本集》(GB2312-80)标准颁布的GB2312-80字符集汉字编码,GB2312-80标准规定:
• 1个汉字用2个字节表示;
• 每个字节只使用低7位,最高位为0;
• 共收录6763个简体汉字、682个符号;
• 一级汉字3755个,以拼音排序;
• 二级汉字3008个,以偏旁排序。
例如啊的编码:
除此之外还有字形编码,如点阵字形编码:
但是上面这种方法不能放大,放大后字符边缘会出现锯齿现象,后面又有了矢量字形编码,矢量字形保存每个字符的数学描述信息,如,笔划的起始、终止坐标,半径、弧度等。矢量字形可以无限放大,笔划轮廓仍然保持圆滑。
3 作业
本节课的作业,就是复习上面的所有知识,并完成下面两道题目!
1 NOIP2012普及组初赛
2 NOIP2014普及组初赛
AI与区块链技术
长按二维码关注