打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
让小朋友懂一点计算机(三)|CPU是如何实现1 1=2的

导言

这一篇小短文需要前面这一篇知识的的理解。二进制与布尔代数

我们知道计算机的大脑是中央处理器CPU,而CPU由运算逻辑部件ALU(Arithmetic and Logic Unit)、寄存器部件和控制部件组成。今天我们要说的ALU是CPU的数学大脑,是负责数值运算的部件。ALU有两个单元,一个是算术单元,一个是逻辑单元。


算术单元


算术单元主要是对数值进行运算。

首先是加法

首先我们来做一个简单的1 bit数据的加法,也就是两个一位二进制的加法。情况是这样

0 + 0 = 0

0 + 1 = 1

1 + 0 = 1

1 + 1 = 0但是要进一个1,这是因为1+1=2,但是二进制里没有2这个数的表示,因此需要进位,十进制的数2转换为二进制数就是10。

如果把0和1分别代表真和假,你会发现刚好布尔代数里的XOR操作刚好满足可以对应着这四种基本运算,但是1+1需要进位比较麻烦,因此我们可以加一个与门进行AND操作,如下图:

半加器的内部结构

CARRY输出进位标志

而SUM则输出除了进位之外的和

这样,两二进制数相加就会得到两个标记,而这两个标记的组合则可以表示所有可能的情况,虽然只是两个1 bit数据相加的情况。现在,我们把这种电路结构固定下来,并且形成新的一个电子元器件,称之为半加器。

半加器

但是这还是有一点点问题,的确,两个1 bit的数据相加,用半加器的确没啥问题,但是如果是多个bit的数据相加呢?半加器好像不行。就像下图中的红框中的情景,除了两个数自身的相加外,还得把进位的 1 也要加上,这就是三个数相加的问题。

3比特的数据相加

为了解决这个问题,全加器出来了,全加器是两个半加器加一个或门组成。它的输入有三个值,分别为数A,数B,还有进位C,它的输出有两个值,分别为 进位。如下图:

全加器的内部结构

因此,加法器里最关键的两个部件我们有了,那么现在我们可以制作一个8位加法器,8位加法器由1个半加器和 7个全加器组成。如下图:

8位加法器

首先数A的第一位A0与数B的第一位B0使用半加器相加(PS.程序员的世界里一般第一个数的下标为0,这一点很常见),然后输出相加的 还有 进位标志,然后A1与B1 还有进位标志 相加,然后输出和和进位标志。一直这样下去,直到A7与B7相加,但是注意哦,如果A7 与 B7相加产生了进位,那就产生了 溢出,溢出就是数值存放所需要的位数已经超过了用来表示的位数。这就像一个100毫升的杯子,你倒入了50毫升的牛奶之后,又倒入了70毫升,那么,牛奶就会从杯子里溢出了。因此,要表示越大越复杂的数,我们需要更多的位数。

减法

在这里,我需要把减法单独拎出来讲一下。因为减去一个数等于加上这个数的负数,例如 10-8 = 10 + (-8),这样就把所有的加减运算都转化为了加法运算,前面我们说到过,二进制中的第一位如果是1 的话则表示这个数是负数,如果是0的话,则表示这个数是正数,那么如何在计算机内部做到正负数之间的加减呢?

当然,我们已经解决了这个问题。我们是通过特殊的存储方式来解决的。

机器数

首先我们需要了解一下机器数和原码反码补码。

一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。数字一般以补码的形式存放在计算机中。

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值

原码, 反码和补码的概念.

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原码= 0000 0001

[-1]原码= 1000 0001

反码

反码的表示方法是:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

补码

补码的表示方法是:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)。实际中,计算机内部是存储补码的(至于怎么存储的,后面会讲到)。

[+10]补码 = 00001010

[- 8 ]补码 = 11111000

相加得:

两个8比特数相加

10 + (-8) = 2

[+2 ]补码 = 00000010 = 十进制的2

你会发现多出了一位,这一位是进位得到的,它会被直接丢弃掉,然后就直接得到二进制数00000010,就是十进制的2。这一结果的出现并不是巧合,这是人为设计的结果。

补码的出现使符号成为了运算的一部分,这种设计使计算机内的运算只需要加法,而没有减法。

更多细节详见链接http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

乘法与除法

讲完了加减法,那么乘除法又是怎么运算的呢?乘法电路和加法电路没什么本质区别,只是有更多的加法器。

除法

先直接来个例子,12/5 = 2.4,这一点我们都知道,当然,我们小学好像学过12/5 = 2 余2 ,这也对,为什么是这样呢,因为

12 - 5 = 7 | 7- 5 = 2 | 2好像减不了5,因为2比5小,好了,那么我们现在就知道 12/5 = 2 余 2 ,如果你只算需要整型数据,那么这就够了,Int a = 12/5 那么a = 2,但是如果你需要浮点数,那么就可以将余下的2乘以10然后再不断的减去5,你就可以得到浮点数float b = 12/5 那么a的值就是2.4。

乘法

还是直接举例子 12* 5 = 60,你可以看做 12+12+12+12+12 = 60 ,也就是5个12相加,当然也可以看做12个5相加,这很笨,但是很管用,他一般运用在很简单的ALU上,例如玩具,普通家电中。

在高端的计算机中,有专门的部件来进行相关的乘除法运算,但其根本,还是由很多的逻辑门构成。


逻辑部分


除了算术运算,ALU还需要做一下不是很侧重于运算的工作,比如,判断一个数是不是0(因为两个数如果相等的话,相减就是0,所以这个可以判断两个数是否相等),是不是偶数,是否溢出,这些都是ALU逻辑单元所需要做的事情。

下图为ALU判断一个数是否为0 的电路结构。

这里是判断一个8比特数是否为0的电路结构

一般我们使用这个符号将ALU抽象出来,这个有点像大写的V。

ALU标识

总结

其实无论多么高深复杂的功能,都是由一个个简单的晶体管拼接而成,电路这种特殊的结构使得它天生适合于二进制。二进制天然不是电路,电路天然是二进制。

资料来源

特此鸣谢 The Crash Course

讲述原码补码反码的网页链接 http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
为什么计算机用补码存储数据?
原码反码补码
原码、反码和补码
分享:负数的二进制编码——越是基础的越是要掌握
原码, 反码, 补码 详解
数制和码制
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服