一、为什么计算机使用二进制?
其实也可以使用十进制,但是使用二进制的计算机更容易制造。就像铜比铝导电性好,但是电子产品还是大量使用铝,因为铜储量少更贵。
二、那为什么使用二进制的计算机更容易制造呢?
因为二进制只有1和0,正好对应真值和假值,10和真假可以相互转化,所以二进制的算术运算就能转化成逻辑运算,而逻辑运算的电路比算术运算的电路更容易设计和制造,因为真值和假值正好对应电子器件的两种状态,比如电路的导通和断开、晶体管的导通和断开、磁原件的正负剩磁、电位的高低等。记住一个原则,状态越少,容错率越高,越容易设计和制造。
三、如何制作逻辑运算电路?
(一)使用什么东西制作逻辑运算电路?
我们使用晶体管制作逻辑运算电路。
1948年贝尔实验室的肖克利等人发明了晶体管。
晶体管泛指半导体电子元件。晶体管有很多种类型,包括二极管、三极管、场效应管,每种类型又分为NPN型和PNP型。
晶体管就是个开关,它可以打开和关闭电流。
晶体管电路有导通和断开两种状态,这两种状态就可以作为二进制的基础。
下面我们讲解一下PNP型晶体管,当b处电压>e处电压时,晶体管中c极和e极断开;当b处电压 PNP型晶体管,高电平断开,低电平导通。假如此时,我们把高电平作为“1”,低电平作为“0”。那么b极输入1,就会导致电路断开,如果这个电路是控制计算机开关机的,那么就会把计算机关闭。这就是机器语言的原理。 NPN型晶体管与PNP型晶体管正好相反,高电平导通,低电平断开。 (二)如何用晶体管搭建逻辑运算电路? 基本逻辑运算包括非、与、或、异或、与非、或非、异或非(同或)。 其他更复杂的逻辑运算都是由这些基本逻辑运算组成的。 这些基本逻辑运算对应的电路叫做门电路,都是最基本的逻辑电路,由若干晶体管组成。 之所以叫“门”,是因为它就像一个转换门,把进入的信号转换成输出的信号。 下面只讲解非门、与门、或门。 1、非门(not) 非门电路用来实现非逻辑运算。 非门电路又叫“否”运算,也称求“反”运算,因此非门电路又称为反相器。 AY0110下面是使用一个NPN型晶体管组成的非门电路。 A为高电平,T1导通,Y为低电平;A为低电平,T1截止,Y为高电平。 2、与门(and) 与门电路用来实现与逻辑运算。 与门电路是指只有在一件事情的所有条件都具备时,事情才会发生。 ABY000010100111用2个NPN三极管搭建与门; A和B都为高电平时,T2和T3都导通,此时Y为高电平。 3、或门(or) 或门电路用来实现或逻辑运算。 或门电路是指只要有一个条件满足,事情就会发生。 ABY000011101111用2个NPN三极管搭建或门; A或B只要有一个是高电平时,T4或T5就导通,此时Y为高电平。 其他的异或门(xor)、与非门、或非门、异或非门(同或门)都可以使用上面3种组合而成,这里就不具体介绍了。 为了方便画图,把门电路符号化。 四、如何实现算术运算呢? 现在我们有了基本逻辑运算电路,可以实现逻辑运算,那么该如何实现算术运算呢?也就是如何把二进制算术运算转换成逻辑运算? 算术运算包括加减乘除。 (一)我们先讲加法。 如何把加法表达式转化成逻辑表达式? 下面就是A+B的示意图。 Cin是输入进位,Cout是输出进位,Sum是和。 这些符号都表示一个二进制数,要么是1,要么是0。 因为10和真假可以相互转化,所以可以把A+B+Cin转换成以下的逻辑表达式: Sum=A xor B xor Cin Cout=(A and B) or (Cin and (A xor B)) 然后根据逻辑表达式,制作逻辑电路。 上面这个电路就叫做全加器。 为了方便画图,我们把全加器也符号化。 因为这个全加器只能计算1位二进制,而我们要计算的数通常是32位的,所以我们需要32个全加器,连起来。这就构成了三十二位加法器。下图是五位加法器,仅为了举例,因为32位太难画了。 我们把输入与拨码开关相连,就能手动输入数字了;把输出与灯泡相连,就能看到输出结果了。 有了加法器,我们把十进制数转化成二进制,然后手动给A和B输入二进制,比如A是12=01100,B是10=01010,然后一瞬间,我们就得到Sum的值是10110=22。 但是,当给A输入31=11111,B也输入31=11111,那么得到的Sum是11110=30,结果怎么不对?没错,结果就应该不对,因为加法器是5位的,能表示的最大值是2^5-1=31,而31+31=62>31。这就是产生进位了,也叫做溢出。这是输入和输出的二进制位数相同必然导致的结果。那么我要计算31+31怎么办?解决方法有两个:1、增加加法器的位数,比如5位变成6位,6位二进制最大值是63,而31+31=62<63,这样就能表示62了。2、你只能限制加数的大小,保证两个数的和小于32,比如可以计算10+10,但是就是不能计算31+31,没办法,这是计算机运算的局限性。 为了画图方便,把加法器也符号化。 (二)减法怎么实现呢? 1、负数怎么表示? 在做减法时,结果可能是负数。但是,运算电路的输入输出都是二进制1和0,它并不区分正负数,或者说它总是把二进制当成正数。 既然它总是把二进制当成正数,那么我们如何表示负数?比如1-4=-3,这个-3怎么表示? 答案就是,我们人为规定了一套用二进制表示负数的规则。这个规则就是,使用一个数的补码表示这个数的负数。 规定:-x的二进制就是x的二进制的补码。 两个二进制互为补码,当且仅当,两个二进制的和是2w。w是二进制位数。 在数学上两个二进制的和是2w,但是因为计算机实际运算时加数与和的二进制位数是相同的,所以最高位的进位会舍弃,这样就只剩下w个0了,就变成互为补码的两个二进制的和实际上为0。 比如,1111 1111 + 0000 0001 = (1)0000 0000,所以1111 1111 和 0000 0001就互为补码。 因为二进制位数固定相同,最高位的进位会舍弃,所以相当于两个的和是0。 2、减法怎么做? 这样规定之后,就能用二进制表示负数了。那么减法怎么做? 减一个数就变成加这个数的补码了,也就是A-B=A+(-B)=A+B补。减法实际上就变成取补运算了。这样就能复用加法器了。 求x的补码,就是用2w - x。注意取补的过程是人做的,不是加法器做的,人把手动求出的补码输入加法器,加法器再把补码相加,这样就能得到结果了。 比如5-1,实际上就是5+(-1),-1的二进制是1的二进制的补码,也就是2w-1。我们把5的二进制和-1的二进制分别输入加法器,就能计算出结果了。 下面我们看几个减法运算的例子,体会一下减法运算的正确性。 比如,-1-3 = -4,实际上就是(-1)+(-3)=-4。如果能证明-1的二进制与-3的二进制的和就是-4的二进制,是不是就证明了计算的正确性? 根据规定,-1的二进制就是1的补码,为2w-1。-3的二进制就是3的补码,为2w - 3。-4的二进制就是4的补码,为2w - 4。如果能证明(2w-1) + (2w - 3) = 2w - 4,那么就证明了计算的正确性。 证明: (2w-1) + (2w - 3) = 2w+2w - 4,因为实际运算时二进制位数固定,最高进位要舍弃,所以结果要取余。 2w + 2w - 4 mod 2w = 2w - 4,取余之后正好是-4的二进制,所以-1的二进制与-3的二进制的和就是-4的二进制。 那么减法电路就是下面的样子,其实就是复用的加法器: A-B=A+B补,复用上面的加法器。就是手动给A设置-1=11111,给B设置-3=11101,然后一瞬间,得到Sum的值是11100=-4。 同理下面几个例子也是正确的。 -3 + 1 = -2,(2w - 3) + 1 = 2w - 2,也是正确的。 3 + -1 = 2,3 + (2w - 1) = 2w + 2 mod 2w = 2,也是正确的。 -2 + 2 = 0,(2w - 2) + 2 = 2w mod 2w = 0,也是正确的。 可见用补码来表示负数,从而实现减法是正确的。 3、一个二进制到底表示负数还是正数? 自从我们人为规定了负数的表示方法,就出现了一个棘手的问题。那就是一个二进制可以有两种解释,既可以当作正数,又可以当作负数,那么一个二进制到底表示负数还是正数?比如8位二进制1011 0110。它相当于十进制的多少? 这个时候就又出现了一个规定,规定:二进制有两种解释方法,一种是把它看作有符号的,另一种是把它看作无符号的。当看作无符号时,二进制应该当成正数,表示范围是0 ~ 2w-1。当看作有符号时,以0开头的二进制应该当成正数,以1开头的二进制应该当成负数,表示的范围是-2(w-1) ~ 2(w-1)-1。 这样规定之后,再回答“8位二进制为10110110。它相当于十进制的多少?”,你必须先问,把它看作有符号数还是无符号数?如果是有符号的,它就是负数-74。如果是无符号的,它就是正数182。 当然无论是把二进制看作有符号的,还是看作无符号的,计算机在运算时都是按照同一套方法计算,运算电路是无法区分符号的,区分符号是人做的,把二进制解释成十进制也是人做的,不是运算电路做的。这就是二进制的麻烦之处,它们只是一些0和1,本身并没有任何含义,含义取决于你如何看待它,选择何种解释方式。 比如,下面的运算就有两种解释方式: 一种解释是把二进制看成无符号的,那么加法器的输入输出就是A=31,B=29,Sum=28。 另一种解释是把二进制看成有符号的,那么加法器的输入输出就是A=-1,B=-3,Sum=-4。 这两种解释的运算流程完全一样,内部的二进制完全一样。记住,运算电路根本不区分符号,区分符号是人做的。 注意,把二进制看作无符号时,是把所有二进制都看作无符号的,看作有符号时也是一样,不能两者混合。 (三)取补运算 上面做减法时,取补是人手动做的,那能不能让计算机自动做呢?答案是能。 这时要用到一个定理,就是:一个二进制的补码=这个二进制的反码+1。 比如,位数w=4,1的二进制是0001,1的补码是24-1,二进制是1111。而1的二进制的反码是1110,加1之后正好等于1111。 下面我们证明一下这个定理: 反码,就是把二进制的每一位取反,1变成0,0变成1。 那么,x+x反=1…1(w个1)=2w-1 结合x+x补=2w,两个公式相减得到 x反-x补=-1,也就是x补=x反+1。 证毕。 下面是取补码的电路图 为了求1的补码,给A输入00001,B固定是0,Cin固定是1,那么一瞬间得到Sum=11111,也就是00001的补码。 有了取补码的电路,那么减法的电路就改进成下面的样子: 为了计算1-3,给A输入1=00001,给B输入3=00011,C固定为0,D固定为1,那么一瞬间得到最终结果11110=-2。 五、如何选择运算类型? 上面我们讲了如何制作加法和减法电路,它们是独立的两套电路,但是它们有重复的部分,总感觉有些浪费,能不能把两套电路合并成一套电路呢?答案是能。 但合并之后,出现一个问题,那就是如何选择运算类型,做加法还是做减法,我们如何控制?这就需要添加额外的电路,这种电路的功能就是控制做何种运算,就叫做控制电路。 下面就是合并之后的算术运算电路: 增加了一个输入F,用来控制做加法还是减法。 当F=0时,B的每一位与0异或,得到的还是B。加法器的Cin为0。此时就是做A+B。 当F=1时,B的每一位与1异或,得到B反。加法器的Cin为1。此时就是做A+B反+1=A+B补=A-B。