这几天想要开始学习系统的原理,本身硬件的系统已经下潜到底层与硬件的各个组成部分进行交互,例如:对CPU的资源管理;内存的管理等。
既然要研究底层,无非从最基础开始,二进制绝对是计算机的灵魂。二进制使用逻辑运算实现各种数的算数运算是学习二进制的基础,下面就来分析一下二进制的加减法的实现方式。
回想一下,我们学习十进制加法的时候是先从1位数开始,这里我们也从1位数开始学习二进制的加法。
下面用真值表来表示1位二进制的加法。
X | Y | X+Y | 进位 |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
从表中我们可以看到实现1位二进制加法的基本元素有四个:加数X、加数Y、和X+Y(这里的和只有本位)、进位。
如果从函数的角度来看就是有两个输入,两个输出。
下面我们来分析一下从输入到输出的运算,注意二进制都是用逻辑进行运算,基本的逻辑运算有与、或、非三种。
上面的1位加法属于半加器,因为我们没有考虑来自前面运算的进位,但实际上加上前面的进位运算也很简单,实际上就是用两个半加器结合来,各位可以自己去思考一下。
实现了一位全加器之后,就可以实现多位全加器了。
减法可以转换成加一个负值,比如12 - 8,转换成12 + (-8),这两个是等价的。这就引出另一个问题,计算机怎么表示负数的?
按正常思路,可以用最高位代表符号,0代表正,1代表负,比如一个8位二进制:0000 0001是1,1000 0001是-1;这看起来很自然。但是你马上会发现:0000 0000和1000 0000这两个值出现矛盾了,从字面上理解这两个都是0,应该是相等的。但从内存上看这两个字节又是不相等的。
计算机先驱们用另一种方式存储负数,首先对于一个整型,我们要先明确它是有符号的还是无符号的,同样的存储,有符号和无符号代表的数值可能是不一样的,以一个8位数为例:
二进制 00000000 00000001 00000010...01111111 10000000 10000001...11111110 11111111
无符号 0 1 2........127 128 129........254 255
有符号 0 1 2........127 -128 -127.........-2 -1
有符号数到达127之后,再往后是-128,后面是-127,-126...一直到-1,这样8位有符号数的范围就是:-128~127。
虽然从二进制看一直在涨,但到10000000以后,其表示的含义却是从负数的最大值往下减。10000000,10000001这些二进制被称为负数的补码形式,所以计算机是用负数的补码来表示负数的。
负数的补码和对应的正数有一个奇妙的运算关系:
在计算机中,正数以正常方式存储,而负数是用补码的形式来存储的。
> 计算机内存| 00000111 | 11111001|
| 7 | -7 |
如上所示,用补码存负数有一个好处,就是可以用加法代替减法。如下所示
5-3
=5+(-3)
=(00000101)+(11111101)
=(00000010) 正数
=2
4-6
=4+(-6)
=(00000100)+(11111001)
=(11111101) 补码代表负数
=-2
原文:https://www.cnblogs.com/huguang-dazongdu/p/14683893.html