数字电子技术大致可以分为两部分,魂和体.魂指的是逻辑代数和计数系统,编码;体指的是门电路的实现以及基于门电路上的各种元件.
逻辑代数的主体是数理逻辑,属于逻辑的一种,是二值逻辑,主要关注于信息的处理.
计数系统和编码主要关注于信息的表示.
门电路的实现主要关注于逻辑代数的实现,从而实现信息的处理.
首先,我们先了解计数系统和编码系统.
由于二进制能使得电路更简单,更有效,所以现代的计算机基本都是二进制.不过,好像曾见过一篇文章在探讨三进制的计算机,据说更有效,在此就不展开了.
又因为人类熟悉十进制计数法,很难习惯二进制计数,所以就必须实现十进制和二进制的转换.在了解两者如何转换之前,先介绍一下必备知识.
在位置计数法中,最核心的概念就是位权.位权描述的是在某一个位上的一个单位(即1)相当于多少个单位(即1).对于n进制而言,假如整数位为k,小数位为m,则第k位整数位的位权为n^(k-1),第m位小数位的位权为n^(-m);再进一步假设第k位整数位上的数为a(k),第m位小数位上的数为a(-m),则第k位整数位上的数的值为a(k)*n^(k-1),第m位小数位上的数的值为a(-m)*n^(-m).
就这样,只要把各个位置上的数加起来,就可以得到这个数的值.如果你加起来后,采用十进制,那么这个数的表示形式就是十进制数,如果采用其他进制,那表示形式就是其他进制数.需要注意的一点是,我们平时所见到的十进制数,二进制数等,都是数的存在形式.比如说,六是一个量的概念,用十进制表示为6,用3位二进制表示为110.当某一个概念只有一种表示形式的时候,把概念和表示形式当做相同来看是没有什么不妥的,但是,如果这个概念有多个表示形式的时候,就应当分开来看.这样,就更容易理解进制之间的转换.
二进制转十进制
第一步:把二进制写成各个位数上的值相加的形式,比如说110=1*10^2+1*10^1+0*10^0;
第二部:按照满十进一的规则,将上式各项相加;
这样就转为十进制数了.
在这里,最关键的就是满十进一,这个规则保证了得到的是十进制数,而不是其他进制的数.
推广开来,如果把满十进一改为满n进一,那么最后得到的就是n进制数,比如说16进制数.
如果n小于或等于10,那么原来的阿拉伯数是够用的,如果n大于10,那么如何表示10,11,12.....就是个问题了.
对于16进制,我们采用A标记10,B标记11,C标记12,D标记13,E标记14,F标记15。这是需要记住的,而且是牢牢记住的,必须能够对ABCDE和10,11,12,13,14,15进行快速转换.
虽然,从上面我们知道可以用满十六进一来实现二进制和十六进制进行转换,但是还有更简单的方法.
从十六进制数的小数点开始,分别从左和从右,每数4位划一斜线,这样就把二进制数分为几部分,如果最左边和最右边位数不够4位,那么补齐4位,然后每部分都展开计算出对应的十六进制数,写在每部分的下面,这样,就得到对应的十六进制数.
如果,反过来,把每个位上的十六进制数分别转化为4位二进制数,就实现了十六进制对二进制的转换.
比如说,
0011/1001/1010
3 9 A
39A就是对应的十六进制数.
原理:每4位二进制数可以转化为一位16进制数.对上面的二进制数的高4位展开为0*10^11+0*10^10+1*10^9+1*10^8 = (0*10^3+0*10^2+1*10^1+1*10^0)*10^8,中4位也同样可以提取10^4的公因式出来,所以可以进行上面的划分,然后直接求出各部分的值,最后组合起来就成为所求的十六进制数.
由于16进制和二进制可以很轻松的转换,而且对于同样的数,16进制比较短,可读性高,所以把16进制当做二进制的常用简记方式,同样八进制也是简记方式,至于如何转换,只须把上面的4位改为3位就行了.因为每一位八进制数等同于3位二进制数.
对于,n进制数转为二进制数,通用的方法就是短除法,局限于整数.(16进制和8进制有特殊法,上面已介绍)
第一步:先把n进制数转为十进制数;
第二步:然后用所得的十进制数去除以2,得到一个余数,这个就是个位上的数;
第三步:用上面的商再除以2,得到一个余数,这个就是十位上的数;
接下来,一直用商除以2,并且得到余数为更高位的数,直到商小于2,这个数就是最高位上的数.
原理:假设这种方法是对的,那么我们把得到的二进制数展开,除以2,得到的余数的确是二进制数中最低位的数;继续除下去,得到的余数逐次为更高位上的数.那么,请问,对于两个数,它们不断地去除以2得到的余数总相等,那么这两个数是否相等.答案是毫无疑问的,绝对相等.所以这种方法是正确的.(这种说法不严谨,有漏洞,严谨的证明需要太多数学字符,太难打了)
到此,我们建立起了以二进制为中心,其他进制为卫星的星型结构,实现了各进制和二进制的相互转换,并且明白其原理(不知道大家懂了没,如果您有更好的表述,证明,欢迎发给我,争取把这个完善了,以后可以做成新手的入门资料,可以省去新手很多时间)
由于人类习惯了十进制,所以在我们的电脑屏幕上的数字或者数字键区的数字,看到的大多都是十进制的.而二进制是计算机能处理的计数法,这就产生一个矛盾:人机矛盾.如何解决这个矛盾呢?有人可能会说,这还不简单,直接转换不就行了.的确,对于小而少的数字,十进制和二进制的转换,对于计算机而言,不用花很多时间.但是面对多而大的数字呢?比如说将23797982734897832784789237412378923787对应的二进制转为十进制,这就有点棘手(其实,还有编程时如何存储这个数,也有点犯难).为此,我们的前辈们在二进制和十进制之间采取了折衷的办法,用8421码来表示数据.由于4位二进制码可以表示16种数值,3位只能表示8种,所以,采用4位二进制码来表示十进制数,即用0000到1001表示0到9,而1010到1111则不表示任何数值.8421码的最大特点就是每4位二进制码等同于一位十进制数.
在我看来,前辈们估计是受了二进制转十六进制的启示,才想出了这个8421码.
举个例子:0011 1001 1000(8421码)=398(10)
但是,由于8421码方便表示,不方便计算(貌似只要是表示和运算时计算机不可避免的矛盾,只要是方便计算的,都不方便表示)
所以,前辈们引入了另一种码:余三码.
余三码是由8421码加上3得到的.
余三码的特征是,对9的自补代码,因而可给运算带来方便,即将两个余三码表示的十进制数相加时,能正确产生进位信号,对产生的"和"必须进行修正:如果有进位,则结果加3,如果无进位,则结果减3。注意,和也是用余三码表示,且所谓正确进位信号是指,当和超过10时,就会产生进位,即和超过1111。
至于余三码和二进制码的转换,可以以8421码为中间量进行转换.
当我们用3(0011)和4(0100)表示某事物的两种状态的时候,从3切换到4,每一位都需要变化,而每一位变化都需要时间,而且会同时变化,这就使得出错的概率大大提高了.
所以,前辈们发明了一种码,叫做格雷码.
格雷码的特点是:任意相邻(大小相邻)的两个数,都只有一位不同.同时,最大数和最小数也只有一位不同而已.(故常被称为反射码或循环码)
二进制码转为格雷码
第一步:在二进制码前加0,然后每相邻的两个数进行异或运算,得到一个数,写在其下面;
第二部:从左到右,把得到的数排列起来就是格雷码.
如下表所示:
A B 异或
0 0 0
0 1 1
1 0 1
1 1 0
无论A,B,异或如何调换位置,真值表总是成立.故A 异或 B等于C,则C 异或 A等于B.
0和1,异或得到1,和0异或得到0,即0有保持原输入的作用.
那么,格雷码的最高位应该和二进制码的最高位相同.
格雷码转为二进制码:
第一步:把格雷码的最高位作为二进制码的最高位;
第二步:将格雷码的第二位和二进制码的最高位取异或得到二进制码的第二位;
第三步:将格雷码的第三位和二进制码的第二位取异或得到二进制码的第三位;
剩下的类似.
我们编码的目的是为了什么?第一是为了存储;第二是为了计算.
对于普通的二进制码而言,我们的要求是能表示我们要求的精度内所有的数,虽然我们打心底是想最好能表示所有的数,但由于计算机是用寄存器或者类似的存储单元来存储数据的.一个寄存器只能存储一位数据(二进制位).所以,肯定不能表示所有的数,最多只能满足我们的精度需要.
由于只要能把数据表示为二进制的形式,那么肯定可以存储.因此,我们在编码的时候更多的是考虑编码是否利于计算.
怎么理解利于计算呢?由于计算机是用电路来计算的,所以利于计算的标准是计算电路要尽可能的简单.
在所有计算中,加法运算是最简单,也是最基础的运算.其他运算其实都可以用加法运算来实现.
比如说,减法运算:减去一个数等于加上这个数的相反数(这个大家都懂)
乘法运算:A*B等于B个A相加或者A个B相加.
除法运算:A/B等于|A|不断去减|B|,直到得到的余数小于|A|,则减运算的次数为商(符号另外处理)
在计算机中,为了表示正负数,我们经常用用二进制数的最高位作为符号位:0是正的,1是负的.
我们把这样的码叫做原码,即最高位表示符号,其他位表示绝对值的大小.
但是根据原码来设计运算电路,太过于复杂,比如说
1001+0001应该等于0000(原码表示)
而电路的物理实现,是用门电路来实现的.如果能够每一位都用相同的电路来实现每一位的相加,那么这样的电路将是相当的高效.(其实,我们是以参与运算的两个数中的相同位和上一位的进位为逻辑变量,并以和和进位为逻辑结果,构建真值表,然后由真值表来找出逻辑函数,由逻辑函数得到对应的电路.)
根据上述知识,我们可以知道原码不适合运算.(比较难以说清楚,以后就会懂的)
因此,前辈们设计了一种码,可以表示正负整数,也方便运算的码:补码.
对于正数,补码和原码相同,对于负数,则如下:
原码转补码:符号位不变,其他位都取反,得到的结果再加1。
补码转二进制码:符号位不变,其他位都取反,得到的结果再加1。
至于为什么补码方便运算,主要是这样构建出来的码每一位都用相同的电路来实现每一位的相加,特别是正数和负数的加法.
(这个很难说清楚,以后再补充)