前面我们已经对计算机系统做了一个大概的介绍,我们讲解了计算机的发展历程,计算机系统的层次结构以及计算机性能指标,那么从本章开始我们就要学习数据的表示和运算。
那么本章的主要内容有哪些呢,我们将要学习数据在计算机当中是如何表示的,以及计算机当中数的计算方法,然后根据计算机当中数的表示和计算方法如何设计一个运算器。这三部分主要内容呢将是我们本章的一个重点。首先我们必须要了解什么叫做数据的表示。数据的表示是指在计算机当中能够被硬件直接识别和处理的数据类型,能够被硬件直接识别和处理是指在计算机系统的指令集当中包含了对这些种类型的数据进行处理的指令。那么这些数据的运算包含在指令当中,我们必须在系统当中用硬件来实现这些运算。在这些过程当中,我们将要分析数据的比算方法,并且呢加以改进,然后在此基础之上我们研究这些算法在计算机当中是如何用硬件实现的,然后给出相应的硬件组成。那么这就是我们第二章数据的表示和运算的一些主要内容。
那么我们进入第一节的学习,第一节呢叫做数制和编码。
我们这一节的主要内容有哪些呢,首先我们将要介绍一下进位计数法,然后我们将要学习不同进制的数制之间是如何相互转换的。然后我们将要学习一种编码方法叫做BCD码。接下来我们将要讲解字符和字符串是如何在计算机当中表示的。最后我们将要讲解校验码。
那么我们来进入第一节的学习,第一节将要讲解进位计数法,那么我们这一节呢有哪些内容呢?
我们将要学习一进制、十进制、二进制数以及其他进制的数。
首先我们来看一下一进制数。那么一进制数呢是指在远古的时候,在远古的时候呢我们是没有手写符号的,那么我们就想要表示一些数,怎么表示呢。它没有符号,我们只能借助一些具体的物体来进行堆积。有一个就是一个,有两个呢就拿两个东西来堆积。
然后不同的堆积就变成了这样的一个一进制表示的这种方法。那么一进制就是说,我们有一个是一个有一个是一个这样的具体物体堆积。这是在远古的时候。
后来我们就发明了十进制的符号。那么十进制是指我们用十个符号来表示从,也就是从0-9这10个符号来表示数,逢10进1。比如就是0、1、2、3、4、5、6、7、8、9,然后表示这9个数字,然后逢10就是当我们到10的时候我们就进1就用就多1位,也就是10位和个位,也就是1、10这样来表示10这样一个数字,就是逢10进1。
这样呢我们就把这10个堆积的数字呢就变成了两个符号,也就是1和0这两个符号表示的就是10。那么10进制呢就是说我们用10个不同的符号来表示数然后逢10就进1。当到了9的时候,接下来一个数我们就是10,10呢我们就进1位,也就是10,10来表示我们的第10个数字。
但是呢在我们的计算机当中是没有办法来表示这样的十进制的,为什么呢?因为这是由我们的物理器件来决定的。我们想要实现一个数字的表示的话,我们将要用物理器件来表示。那么物理器件的物理特性就决定了我们用高电平、低电平或者开关的通断或者开关来表示,所以我们就只有两个数字,也就是0和1,逢2是进1的。也就是我们1下面的一个数字应该是2。那么2是怎么表示呢?逢2进1,就是用10来表示2。
所以我们这10个物体或者说10在计算机内部是怎么表示呢?也就是1010。啊,是逢2进1的,只有两个数字,1和0来表示的。
那么有二进制,还有其他进制的数吗?还有其他进制的数,比如我们的四进制,也就是逢四进一。我们用四个不同的数字,0、1、2、3来表示,然后呢我们3下面的一个数应该是4,然后逢4进一。因为只有4个数字嘛,所以我们就用10来表示4。
所以我们这10个物体的堆积,或者我们的10用4进制数来表示就是22,啊,就是22。这就是我们的四进制数。
那么还有八进制数。八进制也就是逢8进1,用8个不同的数字来表示数,也就是7下面的一个符号就是8。8我们没有这个东西,我们叫逢8进1,所以就是用10来表示8。
所以我们的这个10在八进制数的表示下应该是12。
那么还有十六进制数。十六进制数呢我们就用16个不同的符号。因为我们的数字不够用了,因为我们只有10个数字嘛,那么我们就要借用一些其他的字母。我们也把它当成一个数字,就是把它当成一个表示数的符号,也就用十六个不同的符号来表示十六个数,也就是逢十六进一。那么A、B、C、D、E、F就表示十进制数下的10、11、12、13、14、15。那么到16的时候因为要逢16进1,所以16就是10。
所以我们的10,10这个数字在16进制数下就应该是A,这就是我们的十六进制数。
好的,我们来介绍一个概念,也就是基数。基数就是说我们每一个数位所要用到的不同符号的个数。比如像1进制数,它就只有1个符号,就是这么个东西,所以就是1。那么2进制数的基数就是2,也就是说我们要用两个不同的符号来表示数。4进制数就是4,八进制数它的基数就是8,16进制数它的基数就是16,也就是说我们要用16个不同的符号来表示数。这就是基数的概念。
那么我们来看一下大的基数和小的基数有什么不同,有什么不一样。
那么首先它的位数,大基数肯定是要少的,因为它有不同的符号来表示有更多的符号来表示数,所以它的位数肯定是要少的。我们从上面的例子就可以看出,比如像这个10、16进制数下我们只要用一个符号就可以表示10,而在其他进制数下要有两个甚至4个甚至10个不同的数字不同的符号来表示我们的数。所以基数大的这个进制数它的位数是少的,而基数小的肯定是多的,因为它的符号比较少嘛。
那么运算呢我们以乘法为例,因为10进制数有10个不同的数。所以要如果用两个10进制数进行乘法的话我们就要有100种情况,因为是10个数10个符号来进行乘,所以就有10个符号乘10个符号,就有100种不同的情况。但是二进制数就比较少了,因为它只有两个符号,所以我们只要处理4种不同的情况就行了,比如说1乘1是多少,0乘1是多少。1乘0是多少,0乘0是多少,只有这4种情况。而十进制数就比较多了因为它有10个符号,我们就要用100种不同的情况来表示这样的一个运算。那么,我们这一节课讲的内容呢就比较简单,就给大家讲了一些概念,就是1进制、2进制、4进制、8进制、10进制、16进制是什么,以及基础的概念以及它们之间的对比。
下面我们进入下一节的学习,也就是进制之间的相互转换。那么这是本节最重要的一个知识点,也就是我们第一节,也就是数字和编码当中最最重要的就是我们这一节的内容,所以大家一定要认真地听,掌握它的算法。
那么我们将要讲解十进制和其他进制的相互转换,以及2进制与2的指数进制比如说4进制、8进制、16进制它们之间的相互转换是怎么来转换的。其实还是比较容易的,只要大家认真听,掌握它的算法,就理所当然没有问题了。
那么我们首先来看这个十进制。我们在小学的时候,学习这个算术的时候我们是这样学的,这个75是7是它的10位,5是它的个位。那么这个7和5组合起来就代表是75。那么它的这个值是怎么算出来的呢,我们这个7是10位,所以它就是7*10,也就是这个5是个位,也就是5*1,所以就是70+5,
也就是7*10+5*1,表示的呢就是这个75。就是我们把它就是再进一步地来看一下,
就是7*10^1+5*10^0。那么5所在的这个位叫做个位,所以它就是10的0次方。7所在的这个位置呢叫做10位,所以就是10的1次方,也就是5。我们计算机当中计数是从0开始,所以我们就这样理解,也就是5所在这一位呢就是第0位,也就是10^0。7所在的这一位呢就是第一位也就是10^1。那么这是十进制。
如果我们把它推广到八进制的话,我们这个十进制一样的来计算。也就是说KnKn-1...K2K1K0。那么最后这一位我们把它叫做第0位,最高这一位我们把它叫做第n位。它的赋值它的大小,我们这里所说的大小就是把它转换为十进制,也就是我们能理解的这个数的大小。应该怎么算呢?和十进制应该是一样的,只不过十进制它的基数是10,所以我们就乘10的0次方和10的1次方。而它的基数是r,
这时候我们就乘r的0次方、r的1次方一直到r的n次方。所以这样的一个r进制数,表示成这样的一个r进制数的话,如果想把它转化为十进制数的话,也就是把它们算出它的值,我们平常所说的算出它的值,算出它的值的也就是意思就是说把它转换为十进制的话,就是用它每一位它的这个数字乘以它的这个基数的指数幂,就可以算出我们这个它的十进制的值了。这是我们的整数,如果是小数的话比如说我们在基数后面加个.3,
如果是75.3的话那么它是什么意思呢,
也就是说70+5应该加1个0.3对吧,
那么这个0.3是什么意思呢?也就是3*0.1。
那么0.1又是什么意思呢?也就是10的-1次方。
所以这时候小数我们就乘以10的负指数幂,所以同样的r进制数我们也乘以r的负指幂,
如果在它后面再乘这个样子的话,那么它的值,所说的它的值所对应的10进制数它的值是多少吗。
用k-1*r^-1,再用k-2*r^-2。所以我们的r进制数想要转化为十进制数的话,我们就用每一位它的数乘以它的基数所在的第几号位置,我们就把这个第几号位置放在它的指数上面。
那么我们就有了K1、K0、Kn我们把它叫做位权,也就是说它所在的这一位上的权重,所以就叫做位权。再乘以基数的它在第几号位置上的指数幂就可以了,所以我们的这个算法是非常容易的,我们只要根据十进制是怎么算的,那么r进制它就是怎么算的,我们和十进制一一比对就可以,所以r进制数转换为十进制数大家都会算了吧。很简单,就是用位权,再乘以它的基数,它在第几号位置上,我们就把它放到第几号位的指数上就可以了。那么它是非常容易的,我们只要把这个公式记下来就可以了。
啊,是这样的,这样的一个公式。
下面呢我们就来举几个例子。任意进制是如何转化为十进制数的。那么这个算法是非常容易的,大家只要根据实际十进制数怎么算的你就八进制数就把10替换成它的基数就可以了。那么任意进制数转化为十进制数是非常简单的,那么十进制数如何转换为任意进制数呢这就比较困难了。
那么我们先来看一下这个怎么算的。我们来看一下这样的,刚才我们的公式是这样的。那么这是任意进制转化为十进制数。
如果把它倒过来,我们就要把它除一下。整数部分75,如果我们除以一个r的话,那么它得到的是什么呢?
那么我们得到了一个商,一个余数。那么这个余数正好是K0,也就是正好是这里的5。如果我们再把它除一下,就是用这个商再除以一个r的话,那么我们得到的是前面的余数再加K1。因为K1它乘以r的0次方就没有办法再除以r了,所以余下来的正好是K1,K1是75。十进制数转化为r进制数,我们只要除一下就可以得到它的整数部分了。我们来举一个例子,比如说十进制转化为二进制,余下来的这个就是K0,
那么这时候余的1就是K1。
一直除到结束为止。我们首先得到的是K0,最后才是得到我们的最高位。
所以我们写的时候要倒过来写,得到的是1001011。注意,最后得到的是它的最高位,我们最先得到是它的最低位。D是Decimal(十进制),B是二进制(Binary),得到是最低到高的,最先得到的是K0,最后得到的是这个最高位。
我们还有一种方便的方法,这样写太麻烦了。我们直接用一个短除来表示就可以了。
最先得到的是K0,然后得到的是最高位,所以我们写出来就应该是1001011。
啊,是这样,从下到上写。
除了这种表示方法我们还可以用加个括号再加个下标来表示,就是这样,有两种表示方法。一种表示方法是在下面用大写字母或者小写字母也是一样的,反正D表示的是十进制,B表示的是二进制。或者你加个括号或或者加个下标来表示它是十进制数。这样用短除法,然后余数写在后面的方法大家应该都明白了。那么除了这种方法呢我们还有其他的方法。
那么除了这种方法呢我们还有其他的方法,上面所对应的是它的指数,下面所对应的是2的指数幂。我们可以把75来拆分,怎么拆分呢,找到离它最近的一个指数,r的指数。也就是r的6次方是离它最近的,就是64。
然后后面所剩下的是11,
然后11还可以拆,拆成什么呢?拆成8+3。
8就是离它最近的一个r的指数,然后3还可以拆吗?还可以拆成2+1。
这时候就没有办法拆了,这时候75就可以写成1*2^6+1*2^3+1*2^1+1*2^0。
而这时候是正好是和上面这个二进制的转换是对应的,所以我们就把它写成这样的一个形式。但是这样的方法是比较麻烦的,除非你对2的指数是非常敏感的,你可以用这种方法,我还是建议大家用短除法来求二进制。因为这样是比较麻烦的,你要找离它最近的r进行拆分。这样的话是把这个r进制数转化成十进制数倒过来的一种方法正好是这样一一对应的,这种方法可以用,但是还是建议大家用短除法来求比较简单快捷。这是两种求十进制数转化为r进制数的方法。同样如果是其他进制的数的话我们只要把r换成这个基数就可以了,但是其他进制的数考的是比较少的所以大家只要掌握十进制如何换换成二进制就可以了。这是它的整数部分。
那么小数部分0.3怎么来转化呢?
所以如果我们想要把十进制数的小数转化为二进制数的话,
我们只需要去乘以一个2就可以了。
它的整数部分是0,
所以K-1就是0。
K-2就是1。
那么这样算下去基本上是算不完的。所以我们只需要保留几位就可以了,因为一般来说十进制的小数是不可能精确地转换成2进制的,因为后面总是有一个东西的,所以呢我们只要保留一定精度的位数就可以了。
所以0.3这样的十进制数转化成二进制数呢就是0.01001后面还有一长串,因为是转化不完的,所以我们只要截取一段就可以了,看它的精度要求。所以我们的十进制数和二进制数是如何相互转化的呢,整数部分我们采用的是除以2取它的余数,小数部分我们采用的是乘以2取它的整数。所以呢和短除同样的方法,
这时候呢还是采用的列竖式这样的方法,只不过相反的是,和那个整数部分相反的是,我们最先得到的是离小数点最近的一位,
所以是从上到下来这样写。我们所用的方法就叫做乘基取整法,取它的整数部分来代表它的这个小数。那么这就是十进制数和位进制数它之间的一个相互转换,大家应该都了解了。
好的,那我们接下来讲的是二进制数之间的转换。二进制数之间的转换呢我们考试的重点是2进制数和8进制以及16进制数,也就是说2进制数和2^n进制数之间的一个转换。它的转换就比十进制数之间的转换容易的多了。
我们采用的呢叫做分组转换法。
也就是说二进制数如何转换为4进制数和8进制数呢?
也就是说我们n位一组,每一组转化为相应的这样一个进制,那么2^n就用n位来进行一组。
我们来举个例子就可以知道。
那么如何转换为八进制呢?就把它三个三个一组这样来转换。
16进制也是一样的,4个4个一组就可以了,这样的转换是非常容易的,非常容易的。
那么4进制、8进制、16进制转化为2进制就更容易了,我们只要把它的每一位写成对应的2进制数的形式就可以了。这是比较简单的。
比如我们的3C2.68H,H代表的不是一个符号,H它代表的是16进制数H。16进制数也没有H这个符号,H代表的是16进制数,和刚才的D和B是一样的。它是怎么转换的呢?我们还是每一位写成它的对应的二进制数形式,比如这是2,16进制数2对应的二进制数应该是0010。C(十六进制的C对应是十进制的12)对应的应该是1100,所以3对应的是0011。但是0011呢前面的00我就把它不写了,就是1111000010。和这样的转换是相互的,是一样的。比如68也是一样的,68就是01101000,而00就可以把它舍掉了。所以还是一样的,我们可以这样,它2进制数转化为4进制、8进制、16进制是n个一组转换,我们同样的4进制、8进制、16进制把每一位写成对应的2进制就可以了。所以我们的2^n进制之间的转换还是比较容易的,大家掌握一下就可以了。同样呢我们还可以加括号加下标来表示,这儿就不再赘述了。
我们这一节讲的就是进制之间的相互转化,我们花的时间还是比较多的,所以大家一定要记住,这个是怎么进行转换的。首先我们讲的是10进制和其他进制的一些转换,10进制转换为其他进制呢我们使用的是除基取余和乘基取整方式。而其他进制转化为10进制我们按照那个公式来计算,把每一位按权展开然后进行相加就可以了。那么2进制和2^n进制转化就是分组转换就可以了。好的这就是我们这一节当中的最重点的部分,进制之间的相互转换。希望大家回去多加练习。
上一节我们讲了进制之间的转换,那么一个二进制数,如果想把它转化成10进制数的话,我们就要用按权展开相加的这样一个方法。我们的十进制数想要转化为一个二进制数的话,我们将要采用的是除基取余和乘基取整这两个方法。但是这样的转换还是非常麻烦的,因为要采用一系列的算法还要进行计算。我们想要把它们转换变得简单变得一目了然,那么我们最简单的一个思路应该就是一一对应。我们看到一个二进制就知道它的十进制是多少,我们看到它的十进制就应该知道它的二进制是多少。这样的一一对应的是非常简单的,所以我们就采用一种编码方式,这种编码方式就叫做BCD码,也就是Binary Code Decimal。那么什么意思呢?Binary就是二进制,Code就是编码,然后Decimal也就是说用二进制编码一个十进制。那么我们通常采用的呢是用一个4位的二进制数表示一位的十进制数当中的0-9这10个数码。
那么BCD码呢我们在这一节当中将要介绍三种编码方式。最著名的呢叫做8421码,然后是余三码然后是2421码。值得注意的是,最常用的是8421码,就是大家必须要重点掌握,考试也就最常考的是8421码。
那么刚才我们也已经介绍过了,这个二进制和十进制之间,二进制它在计算机当中是容易表示的,而十进制是我们日常生活习惯所使用的。所以呢一个是方便计算机处理,一个是方便人类的一个习惯。
那么转换呢是非常麻烦的,是这样要用一个公式来转换,转换是非常麻烦的。
所以我们为什么要引出BCD码呢?就是为了我们的转换要快速要一一对应。那么也就是用这个Binary Code Decimal这样一个方式来进行这样的一个快速的转换。一一对应。
那么8421是什么意思呢?它是一种有权码。
它是这样的。我们先把它列出来。它就是它对应的一个二进制数,只不过是用4位来表示的。比如0就是0000,1就是0001,2就是0010,3就是0011,9就是1001,就是用一个二进制数表示一个十进制数0-9这样的一个数码。但是要注意的是,我们的8421码只有0000-1001这10个数字,超过的部分我们是没有定义的。
所以我们一个十进制5,我们直接看到它就是0101。而0101就是一个5。8就是1000。我们把它进行相加,相加是怎么加呢,很简单,就按位相加就可以了。相加之后就是1101,那么这个1101呢是13是没错,但是呢在我们的8421码里面没有1101。那怎么办呢,我们怎么来表示呢,我们可以看到啊,9到这个,我们4位的这样一个二进制数应该能够表示的最大的应该是1111是15。所以我们要把它进一位上去,因为十进制数是逢10进1的,我们想要用二进制这样的一个编码来表示10进制,也就是说我们还是要想它逢10进1,那么怎么办呢?我们就把超过9的部分,所有的超过9的我们都要加一个6,也就是加1个9和15之间的一个距离,也就是加一个6来进行修正。
所以我们的1101就要加1个6。
加6,加6是多少呢,6就是0110嘛。所以我们1101加1个6,
得到的应该是10011。也就是前面这个0001、0011对应的正好是1和3,所以我们只要超过9的部分,所有超过9的部分我们加0110,
也就是加1个6进行修正就可以了。所以这样的就是一一对应了,我们就完美地解决了这样的一个问题。所以也就是说,我们从大于9的部分,也就是从1010到1111这6个是无效的。为什么无效的呢?因为它不在映射表里面。我们想要把它变到映射表里面我们就需要用10进制的逢10进1的这样一个思想,所以我们就要加1个6,加1个0110得到的就是我们的想要的这样一个数据。
所以就是00010011。好的,8421码大家应该都清楚了,要注意的就是说要加6修正这样的一个概念,大家必须要掌握。
好的,这就是8421码的一个映射关系。
我们所要用的呢就是用一个4位的二进制来表示16种不同的状态,但是呢我们只要用到其中的10种状态。
所以,这就引出了我们不同的映射方案。
那么我们下面介绍的第二种映射方案呢,就叫做余三码。余三码是非常简单的,余三码就是在8421码当中加个3,所以每一个数字加3就可以了,大家记住就可以了。只要知道这么个概念就可以了,不需要做太多的纠结,你就把每一个都加上3。
也就是加上(0011),得到的就是余三码,这就是它的对应关系。
那么还有一种方法叫做2421码。我们的8421码为什么叫8421码,这是按照它的权重来赋予的规定。比如说我们最后一位,是它的权值应该是1。第二位,权值应该是2,第三位的权值是2^2也就是4,最高位就是8,所以我们就8421就是这么一个意思。比如说我们9(1001),所以第一位就应该乘8,最后一位就乘1所以应该得到的应该是9,这就是一个8421码。那么2421码呢就是我们把它的权值来改一下,那么最高的这一位它的权值变了,变成了2,所以就2421码。
但是值得注意的是,2421码大于等于5的四位当中,它的最高位是1,而小于等于5的当中,最高位是0。这是要注意的啊,比如说这样2421码,那么5,这个5如果用2421码的时候,我们有两种方法,一种呢就是这个5应该是2+2+1,或者你也可以用4+1,也就是(0101),它也是5啊。为什么不可以呢,我们就规定一下,规定一下这种大于等于5的部分最高位是用1来表示的,这样呢就唯一确定了。好,这就是我们2421码。这个8421码是要重点掌握的,并且这个加6修正也是要重点掌握的,其余的两种了解即可不需要做太多的纠结。
所以我们这一节的知识点就是这样,BCD码我们有三种,不是说我讲的这三种就只有这三种,BCD码有好多种,但是我们书上讲的呢就是这三种,然后重点掌握的是8421码,其他两种了解即可,还有这个加6修正大家必须要重点掌握。
下面我们进入字符和字符串的学习。因为计算机的内部只能识别和处理二进制的代码,所以呢我们的字符想要表示出来,必须要按照一定的规则用二进制的编码来表示。
那么我们这一节的内容将要学习字符和字符串以及汉字是如何在计算机内部表示的。
我们可以看到,我们键盘上的这一些符号,这一些字符在计算机当中是如何来进行表示的呢。
目前呢,我们国际上普遍采用的字符系统是7位二进制编码的ASCII码,它可以表示呢10个10进制的数码,也就是0-9。52个英文带大写字母和小写字母也就是A-Z、a-z,还有一些比如说像这种美元符号$,什么百分号%啊,分号/,减号-,等于号=这一些。
那么我们想要在计算机当中呢表示呢,就是采用这种字符系统来表示,也就是用ASCII码来表示的。
也就是说这些128个字符,我们就用7位的这样的二进制编码在计算机当中来表示。
那么这样的一个7位的二进制编码呢,我们称为ASCII码。这时候呢这些字符在计算机当中就能够进行表示了,我们就把用7位的二进制来对这些数字啊字母啊符号啊来进行编码,然后使它们能够在计算机的内部进行识别和处理。
那么我们来看一下这张表,
我们可以看到这两个部分。在32以前
和126以后,这一些符号呢我们是没有办法显示出来的。这些都是一些用于控制的字符,而从32开始到126结束,这一些符号我们是完全可以显示出来的,我们把它称为可印刷字符,像这个SPC,就是我们的空格。比如像这个33号就是感叹符,像126号就是这样的一个波浪线。那么这一些呢都是可以显示的,也可以打印出来的,所以我们这95个字符呢就称为可印刷字符。那么这张表我们如何掌握呢,不是要你把它背下来,这不可能把它背下来的,考试也不可能这样考你的。我们需要记住的是什么呢,需要记住的是大写的英文字母和小写的英文字母它们是连续的,它们内部是连续的,因为从大Z,大A到大Z它是连续的。从小a到小z它也是连续的,但是大Z和小a之间它是不连续的。你看它中间就是从91号开始到96号结束,这一些符号呢它是其他符号并不是英文字母,像什么方括号[]啊、反斜杠啊这些,所以说我们就是说从大A到大Z它是连续的,从小a到小z它也是连续的,但是大写字母和小写字母之间是不连续的,记住这个就可以了,其他的它的代码是多少你不需要背,你不需要知道65是A,你也不需要知道97是a,你记住当然更好,当然你记不住也不用担心,考试不可能考你的。
也就是说32到126这一些呢是可印刷字符。
数字它也是连续的,是从48到57。大写英文字母它也是连续的,是从65到90。小写英文字母它也是连续的,从97到122。但是大小写之间是不连续的。记住这个就可以了,你不需要背你不需要背它是多少,你只需要知道这一些概念就可以了。
考试怎么考你我们来看一下这道例题。那么这个考你的是什么呢?考你的就是说大A到大Z之间是连续的,所以我们知道A了,我们就完全可以求出H。
那么怎么求呢?‘H’它存放在存储单元M当中,那么存储单元里存放的是什么,存放的肯定是它的二进制的形式,也就是它的ASCII码。
那么‘A’的码就可以推出‘H’的码因为它是连续的嘛,
所以我们用65+(A和H之间的距离),A和H中间隔了七个,从A到H距离是7,所以我们用
这是第一种方法。
那么这是两种方法,大家选你自己喜欢那种方法就可以了。
第二个题目还是一样的,只是和第一条题目换汤不换药。那考的是什么,考的还是说我们ASCII码当中,小a到小z它是连续的,就可以了。
其实和第一条题目解法一样,
所以我们ASCII码要掌握多少,掌握的是说它是一个七位的二进制编码。其次的,我们要知道哪些是连续的,哪些是不连续的就可以了。掌握它这种程度就可以了,会做这样的题目就可以了。好的这是我们的字符。
那么字符串是如何把它存放在一起的呢?字符串是什么东西,我们在数据结构当中就已经学过。
字符串是什么呀,字符串就是把多个字符排列到一起就是一个字符串。字符串呢就是连续的一串字符,通常情况下呢它占用主存当中一些连续的多个字节,每个字节呢存放一个字符。
我们来看一下这样的一个东西。假设我们每一个存储单元存放的呢是4个字节,
那么我们想要存放这样的一个字符串,_不是表示下划线,_表示的是空格。我们这里代表的是空格,因为为了读写方便嘛。读写方便我们就用下划线来表示空格。它是怎么存放在这个主存当中的呢。
它存放有两种方式存放,第一种叫做大端方式,大端模式。那么大端模式就是说我们的存储单元内先存高再存低,
那么小端模式呢是先存低再存高。啊这样听起来比较抽象,我们举个例子就行了。比如我们的字符串这样的一个字符串,IF_A>B_THEN_READ(C)_,
我们把它用大端方式是怎么存的呢?是这样存的。也就是说我们高位的字节呢是先存放的,然后低位的字节再后存放,是这样的。是每一个存储单元的内部是先存高再存低的。这是我们的大端模式。
然后呢我们再把它转化为相应的ASCII码进行存放。啊,就是这样,为了读起来方便我们用十进制数表示,其实在它内部还是用的是二进制数。那么这是大端模式。
那么小端模式是怎么存放的呢?是在每一个存储单元当中啊,就是将4个4个的一组当中,我们是把低位字节先存放,也就是先存放A然后存放空格然后存放F然后存放I,是这样的啊。是每一个存储单元内部先存高位字节的叫做大端模式,先存低位字节的叫做小端模式。记住这一张图就可以了,大家再巩固地理解一下。好的,我们这就是字符串在计算机内部是如何存放的是有两种方式,就是先存高的高位字节或者先存低位字节是这样。好的这就是我们字符串,了解即可。
下面我们讲的是汉字。我们知道ASCII码它只有7位的二进制数,但是呢我们汉字有多少呢,我们常用的汉字就有两千多个了再加上一些不常用的所有的汉字再加起来,我们1981年的这样的一个国标,GB2312-1980当中,我们规定了每一个编码用两个字节表示。然后收录了3775个一级汉字,3080个二级汉字以及还有一些其他的符号,我们共收录了7445个这样的总共的汉字加符号。我们这样的汉字编码呢,有三种表示。它包括汉字的输入码,汉字的内码和汉字的字形码三种,分别表示分别用于什么呢,分别用于输入、内部处理和输出,就是输入我们用输入编码,然后内部进行处理的时候用它的汉字内码,然后输出的时候我们用汉字字形码来表示。
那么我们的这样的汉字呢是用区位码来表示的,一共有94个区。每一个区呢,有94个位置。
我们来看这张图,啊就是这样的。我们的每一个汉字都有它的一个编码,它是用两个字节来表示一个汉字。每一个字节呢用一个7位的码,把汉字和符号呢排列成一个94行、94列的一个二维代码表当中。区位码呢是一个4位的10进制数,啊前两位是区码,后两位是位码,所以我们把它称为区位码。
比如说我们这个啊啊,1601,前两位也就是16代表的是它的区码,
01代表的是它的位码。那么16我们用,一般呢在计算机当中我们用16进制来表示一个地址是10H,
然后呢01就是01H,H代表的是16进制数,就是这样。所以我们就把它称为一个区位码。了解即可,不需要太多地关注,然后有这么一个概念就可以了。好的,这只是我们那一个区位码。然后有一个叫做国标码。
国标码呢它是什么意思呢?它就是我们把我们的10进制的一个区位码先把它转化为16进制数,累计转化完毕了。再在每一个这样的一个16进制数上加上20,也就是20H。然后就可以把我们10进制的一个区位码转化为我们的国标码,加上20H,我们就把这个啊的区位码对应的国标码就表示出来,也就是30H、21H,这是我们的国标码。
然后我们想把它变成一个汉字内码那应该怎么办呢?是在国标码的基础上每一个字节再加80H。我们这样就变成了一个汉字内码。了解即可,什么是区位码,什么是国标码,什么是汉字内码。
那么汉字内码我们进行计算机的内部处理,
我们还有输入码和输出码,刚才我们已经讲过了,也就是输入输出,一个是输入编码一个是汉字字形码。这个我们刚才已经讲过了,我们就了解一下就可以了,汉字这部分不要花太多力气,了解一下,听我讲完就过一遍就结束了。好的那就是我们这一节的所有内容。
我们这一节讲了字符和字符串,讲了ASCII码,讲了这个字符串在计算机内部如何表示的,大端模式和小端模式。还有我们汉字的区位码、国标码、汉字机内码,然后我们的输入和字形码这是用来干什么的,知道这些就足够了。
在本节的最后我们将要讲解校验码。
关于校验码,我们需要掌握的呢是校验的原理,奇偶校验码、汉明校验码以及循环冗余校验码。其中奇偶校验码是这一节的重点。
那么我们为什么要提出校验呢?这是发生在这样一个通信的过程当中。因为我们的这个信道啊,它有充满着各种各样的一个风险。我们在传递一个信息的时候,可能会发生这样一个跳变。就是信息就发生了一些变化,因为有各种的风险,有各种的这样一个物理环境改变。有各种风险,有各种的物理环境的改变,所以我们的接收方就必须要判断我接收到的信息是否发生了变化,是否就是和你发送给我的信息是一样的,有没有经过一些信号的跳变啊。所以呢我们就必须要有这样一个校验码。
比如说我现在,假设我们的发送方要发送给我们的接收方A和B,那我们就要对A和B对它进行一个编码。我们要如果我们用两位的这样一个二进制进行编码,我们用00进行表示A,用01表示B,然后剩下的10表示C,11表示D。
还有一种方法呢我们可以用00表示A,11表示B,其余的都叫做非法字符也就是说如果我收到的是01或者我收到的是10的话,我敢保证肯定出错了。为什么呢?因为我的这样一个编码方案当中就没有10和01。那么我们来看一下,哪一种编码方案是比较好的?
我们提出这样的一个定义,我们把两个合法码字对应位上的数字不同位的个数我们称为码距。那么什么叫做合法码字呢?就比如我们的第一种方案当中,00、01、10、11它都是合法的。因为分别表示A、B、C、D。那么它的码距是多少,它的码据就是1。为什么呢?因为不同的位的个数只有1个,就是A和B啊,A和B,00和01只有1个是不同的。那么编码2呢,编码方案2它的这一个码距是2,为什么呢?因为00和11有两个是不同的,并且呢01和10这两个是非法的,因为合法的只有00和11。所以呢第二种方案它的码距是2。
那么码距是1和码据是2到底有什么不同呢?假设我这个发送方给接收方发送的信息是A,也就是发送的信息是00,这时候它经过这个信道的传输之后有了一些变化,就是因为这个物理环境啊什么的,它改变了,突然变成了01。那么我的接收方这时候接收到了01之后,我如果是第一种编码方案的话,我不知道就到底是原来它发送给我的就是B,还是说原来发送的是A,然后呢经过了一些出错变成了B,这样我就没有办法判断了。但是如果我们用第二种编码方案的话,我发送给你的是00,但是你却收到01,这显然可以看出肯定是出错了。因为我的编码方案当中就没有01这样一个东西。所以我们的用码距多一点的显然比用码距少一点的发生故障或者检测故障它的这样一个概率是要多一点的。所以呢码距大一点,就比较容易发现它发生了错误,容易进行一个检验。好的,这就是我们的一个校验的一个原理。那么我们就来看一下我们的第一种校验方法叫做奇偶校验码,那么什么叫做奇偶校验码呢?
首先我们来看一下什么叫做奇校验。奇校验我们就是保证每一段数据当中出现的奇数个1,啊这就是奇校验。偶校验就是出现偶数个1。我们先用奇校验来举一个例子,我们原来的信息是00和01,现在呢我们给这样的一个原编码当中,
这样一个原编码我们加上一个校验位。我们加到最前面。我们要保证啊每一段数据当中出现奇数个1,啊比如我们A,A这个00,它有奇数个1,所以我们前面必须要添1个1。而B呢,B要保证它前面出现的是奇数个1,所以我们已经有了1个1了我们前面就标1个0就可以了。
所以我们的这样一个校验位,啊就是1和0。啊后面是它的信息位,前面是它的校验位。啊我们保证每一段数据当中出现奇数个1就可以了。那么这时候就可以发现,它的码距由1变成了2,因为它有两位不同了现在,我们第一位和最后一位它都不同了,所以这时候我们码距就由1变成了2。而刚才我们已经说过了,就是说如果码距越大的话,它的检错纠错的能力也就越强。并且呢,检错能力肯定是永远要大于纠错能力的,因为发现错误肯定是更容易,而把它恢复错误是比较难的。而我们这时候,我们这一节的重点,我们记住啊,计算机组成原理的重点呢,我们放在校验错误当中,而纠错我们不做要求,你们不要去考虑太多,我们只要发现错误就可以了。那么我们再回到我们的奇校验,奇校验就是说我们保证每一段数据当中出现奇数个1,
就如果它出现你接收到我们的东西之后,发现它出现了偶数个1了,这时候我们可以肯定地说,它肯定发生错误了。因为我们保证每一段数据当中只能出现奇数个1。
但在这时候我们仅需一位校验位就可以了。为什么呢?因为如果我们用两位校验位的话,我们保证它出现奇数是1,前面肯定是要添0的。我们这样一个0添上去之后码距还是2,这样就没有任何效果了。所以我们只需要1位奇校验码就可以了。
那么除了奇偶校验法呢,还有我们下面要讲的把它的规则进行一些更改,进行把它的这样的校验规则进行更改就可以出现其他的校验码,比如我们的海明码和我们的这个循环冗余,循环冗余校验码。
奇偶校验码是这一节的重点,大家必须要掌握。它是怎么来的弄的呢?就是说我们的有效信息是n位,然后在我们的有效信息前面添一个校验位,那么这个校验位是用来干嘛的呢?如果我们现在采用的呢是奇校验码,也就是说我们等的这一段从这个校验位加上我们的有效信息是n+1位,这一段当中我们出现的1的个数是奇数,这就叫奇校验码。偶校验码是偶数就行了。
我们来看一下书上的例题2-3。给出我们的1001101和1010111它的奇校验码和偶校验码。这个题目非常的简单,我们只要把它的定义搞清楚就可以做出来了。奇校验码就在我们的有效信息前面添上0或者1,把它的整个的,整个的这样一长串的这个信息保证它出现的1的个数是奇数,就是奇校验码。出现1的个数是偶数就是偶校验码。啊,就是这样。
就是说我们剩下来的呢它信息位,也就是题目当中给出的这个东西,然后最高位在它前面添一个校验位。
我们的1001101,它出现了几个1呢,已经出现了4个。所以我们想要把它变成一个奇校验的话,就必须把它变成5个
就添1个1。
那么1010111出现了几个呢?已经出现了5个1了。所以前面我们只要添个0就可以了。
偶校验还是一样的方法。
因为出现了4个1,所以前面只要添1个0就行了。
而出现了5个1之后我们要再把它变成偶数的话,前面就必须要添1个1变成6个1。好,这就是我们的奇校验和偶校验。必须掌握,其实也还是挺简单的对吧。我们只要根据它的定义就可以了。我们在有效信息位的前面添上1或者0,保证这一整长串、这一整个当中出现1的个数是奇数还是偶数就可以了。但是,这样一个奇偶校验码虽然用起来非常简单,它还是有局限性的。一般来说简单的东西都是有一定的局限性的。为什么呢?因为我们只能发现数据代码当中奇数位出错的情况,而且还不能纠错,只能发现它出错。你只能发现它奇数位出错,你如果它一下子变成了几位,它变了之后,它的整个当中1的个数还是奇数,那你怎么办呢,那你不就发现不了吗?对吧,所以它还是有一定的局限性的。它主要用于存储器的这样一个数据的检查,和对传送数据它的检查。并且只能检查、只能发现它有没有出错,而不能进行改正。好,这就是奇偶校验码。掌握它的定义掌握它的规则就可以了。
下面要讲的是海明校验码。海明校验码呢是一种广泛采用的是有效的校验码。它呢就把这个奇偶校验码的局限性把它给消掉了,也就是说它是一种多重的奇偶校验码。什么意思呢?我们的奇偶校验码是一整串然后来进行这样的一个恢复的,海明码它就转换一下思路我们就是这样的,我们在有效信息位当中插入几个校验码然后形成一个海明码,就是把每一个二进制位分配到几个奇偶校验组当中。就是把一整个信息分成几个组,某一位出错之后,就会引起有关的几个校验位的值发生变化,这样呢我们就不仅可以检错,还能够知道它的位置。因为它分组进行的嘛,所以它哪一组出错了我们就可以直接定位到哪一组,显然是比这样的奇偶校验码它是一整串进行校验的,它是好处是多一点的。
那么我们再回顾一下,海明码它的设计思路就是把我们的奇偶校验码变成一个分组校验的情况,我们设计多个校验位
然后用校验位标志出我们出错的位置。
比如说我们这样一个1010,它有一位发生错误了变成1011,
那么我们就告诉我们的这个接收方,校验位第一位发生错误了,就是001发生错误了。这样我们就能找到它出错的位置。但是我们想要找到它出错的位置之后,我们需要多少位呢?
我们来给出这样的一个公式。我们有n个信息位,现在我们呢需要k个校验位,就是告诉你哪一位出错了,那么我们所需要的这个k是多少呢?我们k个校验位就可以有多少种状态啊。我们在第一章也讲过了,就是有2^k个状态,因为有k个位嘛,然后就有2^k。每一位是0和1两个状态。
所以就有2^k个不同的这样的一个状态。这时候呢这样的状态我们必须要包括了我们的n+k个位,还必须要包括有一个正确的状态。所以我们这2^k个状态当中,就要包括这n+k的位置还要再包括一个正确的状态,
所以我们2^k必须要大于等于n+k+1。也就是说我们这2^k这样一个校验位,我们所能包括的所能涵盖的这样状态的位数总共有多少个呢?要包括我们整个的位置,还要再包括一个正确的状态,所以叫2^k>=n+k+1。这个公式必须要记住。
那么我们给出一个常用的这样一个表格,如果有n个信息位的话呢,我们一般就有2个校验位。如果有2-4个信息的话,我们有3个校验位。其余的大家记住就可以了,就是都是用这个公式算出来的。
好的,我们来看这样的一个例子。我们的信息是1010,
首先我们要确定k的大小,我们需要用2^k>=n+k+1,
算出来k应该等于3。所以呢我们就需要有3个校验位,
这时候呢我们把信息位也就是1010对应的这个信息位我们把它写成D4D3D2D1,然后校验位我们算出k等于3嘛所以应该是P3P2P1,所以我们呢就把它这样一个整个的7位,7个这样的数字对应的海明码我们标写成H7H6H5H4H3H2H1。
然后我们来确定一下校验位的分布。
我们给出来的分布是这样。也就是说我们的第7位是D4,第6位是D3,第五位是D2,然后在后面加一个P3,然后是D1,P2,P1是这样。校验位是这样的一一对应的,而这个表格要记住。那么它我们有没有发现一个什么规律啊。
就是说我们的Pi是放在了海明位号为2^(i-1)的位置上。你们有没有看到,P1是放在H1当中的,P2是放在H2当中的。然后P3应该放在H4当中,就是这样的一个位置。
然后信息位呢就把其余的位,你先把这个校验位放好之后,剩下的位我们就按照顺序把信息位放下。
好的,这时候呢我们就1010是这样的放的。
那么我们的P3、P2、P1应该怎么计算呢?
我们看到啊,我们首先这个H3,这个第一啊,是在H3当中我们把3换成它的二进制。同样的,
同样的5、6、7也换成它的二进制。
这时候我们把每一位
每一位相同的这一位我们进行一个异或运算。也就是说我们把含有1的部分进行异或运算。P1就用H3异或H5异或H7,啊就是有1的一一对应的这一位进行异或。
同样的,P2就用3、6、7进行异或。
P3呢就用5、6、7进行异或。
什么叫异或,
异或就是相同的为0,不同的为1。0异或0是0,1异或1是0,其余的不同的就是1。
这时候我们就可以算出来了。它是相当于一个偶校验,为什么呢?就是说保证每个都是偶数个1。你有没有发现,这三个位数,不是,0、1你看啊,0、1它有1个1了,我们就必须要再添1个1保证它是偶校验,所以它相当于呢是一个偶校验。
所以我们就可以把它进行算出来。
用这样的公式把它算出来。
这时候我们的海明码就完全地成功了,就已经完全地算出来了。
首先第一步是什么,第一步先确定k的值。第二步然后进行一个分布的一个排列,把Pi放在2^(i-1)处,i-1次方的这样一个位置上。然后再求校验位是怎样求呢,把它的对应的一一对应的这样一个数进行异或。这时候我们的就算出来,然后我们怎么进行纠错呢,纠错就用我们的P1对应的是1、2、4,P1对应的呢是1、3、4,P3对应的是2、3、4,这时候我们进行一个异或。
如果
全是0的话,就说明是对的。但是如果哪一位是错的话,它就变成了1,就是一旦如果我们算出来的如果是1的话,就说明发生了错误。这样呢,我们就可以进行一个检错的功能。我们海明码的求解步骤大家都应该清楚了,纠错我们只需要知道如果对的话全是0,如果哪儿错的话就是1,其他不需要做太多的纠结,我们只需要知道你的海明码是如何进行计算的。把这样的一个计算步骤牢牢地掌握清楚就可以了。
那么我们刚才说的这个分布是这样分布的,我们还可以怎么分布呢?还可以把它D2、D4、D3、D2、D1变成D1、D2、D3、D4,这时候呢
它的这个完全就进行了一些变化了,大家了解一下就行了。
这方面不需要做太多的纠结。
我们最后讲解的呢是循环冗余校验码。循环冗余校验码呢我们直接上例题,把例题搞清楚就行了。它的理论我们不需要掌握,
我们只要会做题就行了。我们看这样的一道题。我们有一个生成多项式,你这个生成多项式怎么来的,你不需要知道因为这个太复杂了。题目当中肯定会给你的,它告诉你有一个生成多项式,然后告诉你有一个信息码现在要你求校验码。那么怎么求呢?
我们先这样,我们首先确定K、R以及对应的这样一个二进制码。那么K是什么,K就是我们的信息位,我们有多少个信息位啊,101001它有6个位,所以K应该是6。
R是什么呢?R就是我们的生成多项式的最高次幂,X的3次方,所以R应该是3。
然后我们的校验码的位数就是K+R=9。
好的这一步我们已经算清楚了。然后我们的生成多项式的对应的二进制码怎么算的呢?是它X前面的系数就是它对应的二进制码,现在是X^3、X^2它前面是1,并且X^0前面也是1,而X^1呢没有所以它前面应该是0。所以这个生成多项式对应的二进制应该是1101。好的,这个大家都清应该楚了。首先把K、R还有一个生成多项式的二进制码求出来就可以了。
那么第二步我们要进行的呢是移位运算。什么是移位运算呢?
就是把它后面补0。就是把这个信息位,
把这个信息码第一位补0就可以了。比如说我们这时候信息码是101001,我们现在呢要把它后面补几位,补R位也就是补3位。补这个就是这个R刚才算出来的R等于3嘛,所以呢我们就要在后面补3个0就可以了。
第三步我们就要进行除法。怎么除?就是用这个东西去除以这个我们的生成多项式所对应的二进制码,也就用这个101001000去除以生成多项式对应的二进制码是多少呢,是1101。
所以用这个东西去除以1101。那么怎么除呢?这时候我们除的呢是叫做模2除法,并且呢不借位的除法。
我们来看一下怎么除,首先,这时候我们要进行的叫做不借位的减法。什么叫做不借位呢?就是不向前面借位,如果相同的话就是0,不同的话直接写1就可以了。这时候0-1=1,1-0=1,0-1=1,1-1=0。
然后再进行一个不借位的减法,变成这样。
这时候最高位是1。
同样的如此反复,
直到最后。
好,我们已经算完了。
这时候得到的一个余数是001。这时候的001就是我们的校验位,得到的最后的余数就是我们的校验位。
好的,所以这时候我们对应的循环冗余校验码就是我们的信息位在它后面加一个校验位,校验位就是我们得到的余数001。这就是我们对应的CRC码。
首先我们确定K,K是什么?K是我们信息码的位数,有6位所以K是6。校验位,校验位是我们生成多项式的最高次幂就是3,所以我们总共有9位的数字。第二步我们要进行的是求出生成多项式对应的二进制码,就是它前面的系数,是1101。然后呢我们进行一个移位,把我们的信息码向左移R位,也就是说我们在信息码的最后补R个0。然后进行一个除法。除法就是最高位如果是1的话就上1,最高位如果是0的话就上0。然后进行一个不借位的减法,然后得到余数之后,余数就是我们的校验码,这时候我们的循环冗余校验码就已经写出来了,就是我们的信息位加上我们的R位的校验码。
然后检错是怎么检错呢?
检错是这样的。如果我们发送的信息是这样的东西,就是我们刚才算出来的这样一个东西。
如果我们接收到没有发生任何错误的话,
我们再进行一个再进行这样一个多项式对应的二进制位,然后进行一个模2除的话,我们得到的呢余数应该是0。因为我们当时是这么算的嘛,我们把这个余数加到后面不就可以完全整除了嘛。最后余数是0就代表没有出错。
但是如果某一位出错了,这时候再用它除的话余数肯定不为0了。所以我们的C2是错的。因为C2是1嘛,出错,所以我们的C2是出错了。但是你有没有发现,如果我们的C9出错了,它没有办法表示了。所以呢我们的这样一个生成多项式说明它是不完美的,它找的也不是太好。但是生成多项式是怎么找的呢?是题目当中给你的,不需要你去掌握。这个是通信原理当中的东西,是比较麻烦的。所以我们只需要会做题就可以了。好的,我们循环冗余码掌握到这个程度就足够了。
校验码。我们所要掌握的呢就是一个码距的概念。然后我们的奇偶校验码,这个需要重点掌握的,也比较简单,只要是保证奇数个1或者保证偶数个1就可以了。海明码它的不等式2^k>=n+k+1这个要掌握清楚,然后它的步骤,把那道例题完全理解。循环冗余校验码是它的步骤,题怎么做就可以了。好的,我们的校验码就讲完了。
最后,我们对我们的第一节进行一个回顾。我们的第一节东西还是比较繁杂的。虽然繁杂,但是还是比较简单的。因为这是我们整个第二章的一个基础。首先我们讲了什么叫做进位计数法,什么是1进制什么是10进制,什么是2进制。然后我们讲解了10进制和其他进制之间的相互转换,只不过这个转换的公式要把它记住。然后它的除基取余和乘基取整然后是怎么计算的大家也要把它记住。然后我们的2进制和2的指数进制是怎么转换的,是分组转换,这个我们要记住啊。然后我们讲的是编码。编码我们讲了BCD码,BCD码呢8421码必须要完全掌握,其余两种了解即可。然后讲了字符和字符串,这些东西都是了解即可。主要记住的呢是我们的ASCII码,ASCII码它当中的题目会怎么出呢我们已经给大家讲了。最后我们讲解的是校验码,校验的原理,奇偶校验码、汉明校验码和循环冗余校验码。这些题目,我们就要把上课讲的题目把它了解清楚。然后重点掌握奇偶校验码,也是很简单的一种校验码就可以了。好的,我们第一节就讲完了。