qakcn
学生会会长
学生会会长
  • 注册日期2008-10-31
  • 最后登录2021-01-05
  • 生日1988-8-18
  • 光玉3394颗
阅读:1441回复:7

科普第27篇——计算机是怎样做加减法的

楼主#
更多 发布于:2012-08-08 01:38
上一次讲了计算机怎样做加法。

我们讲到了半加器。

半加器的逻辑电路:


我们说到半加器能产生进位,但却不能处理低位传上来的进位。于是我们需要另一个半加器来把低位的进位和本位想加,这就是全加器。

全加器的逻辑电路:


我们把两个半加器分别圈出来,这样看得更清楚些:


当然,在设计的时候并不需要完全把全加器的逻辑电路完全绘制出来,我们可以这么表示全加器:


把多个全加器的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——月食
喜欢0 评分0
消失的旅人
光坂基金会
光坂基金会
  • 注册日期2009-05-27
  • 最后登录2019-05-12
  • 生日1991-10-1
  • 光玉2895颗
沙发#
发布于:2012-08-08 06:59
难道是用补码来算?
回复(0) 喜欢(0)     评分
青空に约束を
光坂学士生
光坂学士生
  • 注册日期2010-11-21
  • 最后登录2021-08-21
  • 生日1994-8-13
  • 光玉2247颗
2楼#
发布于:2012-08-08 07:34
好苦逼的演算啊...完全看不懂
[IMG]http://p.dmdjz.com/uploads/2012/08/%E7%B4%A2%E5%B0%BC%E5%AD%902%286%29.jpg[/IMG]
回复(0) 喜欢(0)     评分
红绯鱼
光坂硕士生
光坂硕士生
  • 注册日期2011-03-13
  • 最后登录2023-07-19
  • 生日1991-2-11
  • 光玉7105颗
3楼#
发布于:2012-08-08 08:52
额……头,头略大。我果然还是比较适合十进制啊
回复(0) 喜欢(0)     评分
莫娜の狼
学生会会长
学生会会长
  • 注册日期2012-03-15
  • 最后登录2023-11-05
  • 生日1993-5-31
  • 光玉3633颗
4楼#
发布于:2012-08-08 11:44
同上……头略大……感觉这些我早晚要学的……计算机原理……蛋疼……涉及物理什么的电压什么的……头就大了……
回复(0) 喜欢(0)     评分
银黑劫火
学生会干部
学生会干部
  • 注册日期2012-07-03
  • 最后登录2015-06-15
  • 生日1993-4-3
  • 光玉2216颗
5楼#
发布于:2012-08-08 17:45
负数是不是先用判断指令判别大小,得出是否带负号,以大减小计算?
回复(0) 喜欢(0)     评分
梦幻的夏
光坂学士生
光坂学士生
  • 注册日期2008-10-29
  • 最后登录2014-08-21
  • 生日1986-4-15
  • 光玉3005颗
6楼#
发布于:2012-08-08 20:17
我看我还是改行算了。
回复(0) 喜欢(0)     评分
yue
yue
学生会干部
学生会干部
  • 注册日期2011-07-24
  • 最后登录2020-12-23
  • 生日1990-10-8
  • 光玉1672颗
7楼#
发布于:2012-08-08 21:41
不错 啊 这使我想起我们大学的单片机了!
[IMG]http://p.dmdjz.com/uploads/2012/05/%E8%96%84%E6%A8%B1%E9%AC%BC%282%29.jpg[/IMG]
回复(0) 喜欢(0)     评分
游客

返回顶部