阅读:1560回复:7
科普第27篇——计算机是怎样做加减法的
上一次讲了计算机怎样做加法。
我们讲到了半加器。 半加器的逻辑电路: ![]() 我们说到半加器能产生进位,但却不能处理低位传上来的进位。于是我们需要另一个半加器来把低位的进位和本位想加,这就是全加器。 全加器的逻辑电路: ![]() 我们把两个半加器分别圈出来,这样看得更清楚些: ![]() 当然,在设计的时候并不需要完全把全加器的逻辑电路完全绘制出来,我们可以这么表示全加器: ![]() 把多个全加器的Cin和Cout串联起来,就能组成多位加法器了: ![]() 这是一个8位的加法器,当然,我们还可以组成16位、32位、64位的加法器,这要看你的处理器是打算处理多少位数据的了。 我们也可以更简单地表示8位加法器: ![]() 当然,就算只有8位处理器,我们也是可以处理更多位的计算的,只不过要分成很多步罢了。 我们把一个数字从低到高每8位分成一组,然后先计算低位,再计算高位。 我们可以把8位加法器Cout输出的进位存储到某个地方,在计算高位的时候再取出来从Cin输入进去。这样就能把低位计算产生进位加到高位的计算中去,不管是多少位的数字加法都能计算了。 两个数相加,进位要么为0(没有进位),要么为1(有进位),想想为什么? 比如两个十六位数(当然是二进制数了!)相加: 二进制:1000 1010 0110 0011 + 0010 1011 1101 1111 十六进制:8A63 + 2BDF 十进制:35427 + 11103 我们先计算低位的8位,由于是最低的8位,所以进位为0: 0 + 0110 0011 + 0101 1111 = 1 0100 0010 可以看到产生了进位,我们不用管他,我们现在需要的只是低8位的结果。 然后我们再计算高8位,只不过这次要把进位1加进去: 1 + 1000 1010 + 0010 1011 = 1011 0110 把高低位组合起来,就是最终的结果了:1011 0110 0100 0010 其实,道理和我们把二进制加法拆成一位一位的算(全加器)是一样的。如果我们升级成16位的加法器,那么16位数的加法只需要一次计算就能完成,就不需要两次计算了。所以提高加法器的位数在我们计算更大的数时是有性能提升的。但用16位加法器来计算8位加法,和8位加法器就没什么区别了。 那么计算机又是怎样做减法的呢? 别担心,我们不会设计一种减法器了。我们其实可以把减法转变成加法。 当然,我们不是要把数计算出相反数来,因为我们还不知道负数的加法怎么做呢,甚至我们都还没有说负数怎么表示呢。 不过在此之前,我们先来看看怎么处理减法中的借位问题。 我们还是先来看十进制的减法吧: 3721 - 1357 可以看到,算个位的1-7时,我们需要借位,算得11-7=4,然后算十位的2-5-1(1是低位的借位)时,我们又要借位,算得12-5-1=6,然后百位的7-3-1=3,千位3-1=2,最终结果2364。 其实我们还可以这样算: 先用9999 - 1357 = 8642 然后8642 + 3721 = 12363 然后12363 - 10000 = 2363 最后2363 + 1 = 2364 这是什么原理呢?写成这样大家就理解了: 3721 - 1357 = 3721 - 1357 +10000 - 10000 = 3721 - 1357 + 9999 + 1 - 10000 = ( 3721 + ( 9999 - 1357 ) ) - 10000 + 1 这样虽然还是有减法,但是没有借位了,通过这种方法我们解决了借位的问题。 8642是每一位都用9去减1357得到的数,这样的数所以称作9的补数。比如 5427 的9的补数是 4572 ,17654 的9的补数是82345。 而在二进制中,处理起来就更方便了。下面以4位二进制数为例: 1100 - 1001 首先1111 - 1001 = 0110 然后0110 + 1100 = 1 0010 然后1 0010 - 1 0000 = 0010 最后 0010 + 0001 = 0011 第三步很好处理,只要把四位加法得到进位舍弃就行了。 而第一步就体现了二进制的好处了——用1111减去任何一个4位二进制数,就相当于把每一位数的0变为1、1变为0。更多位数也有这样的规律,如: 11 1111 - 10 1010 = 01 0101 1111 1111 - 1001 1011 = 0110 0100 由于每一位数都是用1去减,所以这样的数就称作1的补数。又由于正好和原来的数1、0相反,所以我们又把1的补数称作反码(相应的原来的数称作原码)。 记得上一次我们说过的逻辑电路吗?要取得一个数的反码,只要把这个数的每一位都执行非运算就行了。我们把每一位都执行非运算叫做按位取反。 但是这个方法还有一个问题,我们还没有一种表示负数的方法。如果结果出现负数,我们就没法处理了。我们也没有一种处理负数加减法的方法。 究竟怎么办呢?且听下回分解。 ==========之前的文章========== 科普第1篇——计算机色彩 科普第1篇补遗——CSS颜色 科普第2篇——光盘 科普第3篇——2、8、10、16 科普第4篇——电池 科普第5篇——浏览器 科普第6篇——字符编码 科普第7篇——加密解密 科普第8篇——移动通信技术 科普第9篇——为什么32位CPU不能支持大于4GB内存? 科普第10篇——智能手机简介 科普第11篇——14.52-14.49=0.0299999? 科普第12篇——为什么HTTPS会更安全? 科普第13篇——计算机语言 科普第14篇——字体(上) 科普第15篇——字体(中) 科普第16篇——字体(下) 科普第17篇——域名解析 科普第17篇补遗——域名 科普第18篇——虚拟内存 科普第19篇——时间 科普第20篇——日期 科普第21篇——日期时间补遗及计算机的时间 科普第22篇——网络(0):基本概念 科普第23篇——二进制的线性编码 科普第24篇——网络(1):OSI模型 科普第25篇——外部接口(第一次修订) 科普第26篇——计算机是怎样做加法的 科普番外篇1——虽然没用但了解一下也很有趣的知识 科普番外篇2——月食 |
|
沙发#
发布于:2012-08-08 06:59
难道是用补码来算?
|
|
2楼#
发布于:2012-08-08 07:34
好苦逼的演算啊...完全看不懂
|
|
|
3楼#
发布于:2012-08-08 08:52
额……头,头略大。我果然还是比较适合十进制啊
|
|
|
4楼#
发布于:2012-08-08 11:44
同上……头略大……感觉这些我早晚要学的……计算机原理……蛋疼……涉及物理什么的电压什么的……头就大了……
|
|
|
5楼#
发布于:2012-08-08 17:45
负数是不是先用判断指令判别大小,得出是否带负号,以大减小计算?
|
|
|
6楼#
发布于:2012-08-08 20:17
![]() |
|
7楼#
发布于:2012-08-08 21:41
不错 啊 这使我想起我们大学的单片机了!
|
|
|