[toc]
概 述
开门见山,我认为有两点最重要的原因:
- 补码可以满足 A +(-A)== 0
- 补码可以让有符号数和无符号数的计算规则一致!
之前在网上查资料,查到的原因大多数都是解释了第一点,而且解释的有理有据令人信服。
所以我这里先说第二点,规则一致,这个是看了 深入理解计算机系统 的公开课学到的。
B站深入理解计算机系统公开课(有中文字幕,强烈推荐)
顺便提一嘴,研究这种问题不要用很大的数去想,就用4位数去思考反而能想的很清楚。
补码让 有符号数 和 无符号数 的计算规则一致
假设我们有一个只有4位的计算机,计算乘法-2 * -3
的值。如果使用原码或者反码进行计算,
注意,乘法的计算规则是:直接截断保留最低4位,保留后的最高位即为符号位。
使用补码计算
-2 的补码: 1110 转换成无符号数(十进制): 14
-3 的补码: 1101 转换成无符号数(十进制): 13
无符号数 14 * 13 = 182
将182 转换成 二进制 并且只保留最低 4 位: 0110 (0110的十进制是 6, 等于正确答案)
使用原码计算
-2 的原码: 1010 转换成无符号数(十进制): 10
-3 的原码: 1011 转换成无符号数(十进制): 11
无符号数 10 * 11 = 110
将110 转换成 二进制 并且只保留最低 4 位: 1110 (1110的十进制是 -6 或者 14,均不等于正确答案 6)
如果你觉得这是个巧合,那么可以自己试几个数算一下,或者用反码也算一下,看看是什么结果。
有符号数 和 无符号数 计算规则一致 有什么好处?
可以简化硬件的计算,因为硬件就是单纯的电路板,它可不知道什么符号位,它能做的就是把接收到的两个值做运算。
如果计算机使用原码,那么是不是cpu需要准备两套运算电路,运算前还要做个if else
判断?一套给有符号数用,一套给无符号数用。这样子会造成极大的资源浪费。
但是如果我们使用补码,就可以让硬件无脑的计算再截断好了,反正最后的值不论是 有符号 还是 无符号, 都能得到正确的答案。
补码可以满足 A +(-A)== 0
由于讲这个的太多了,这里就简单说一下(不写反码了,直接用补码举例)。
用整数 1 来做个实验,
1 的原码是 0001,补码是 0001。
-1的原码是1001,补码是 1111。
如果你让 1 和 -1 的原码相加,那么他们很明显不得 0, 但是补码相加溢出再截断,最后等于0 。
至于为什么会这样?因为补码的定义就是这样啊
用我自己的话总结:补码就等于现有的位再加一位,新加的位等于1,其余都为0 。减去当前的原码,就成了补码。
用例子来说就是 10000 (总共5位) 减去 1 的原码 0001, 就等于 1 的补码 1111 。
10000 - 00001 = 1111
快速看出补码的十进制小方法
用 -1 举例 , -1 的补码 1111
这四位不是对应着 8 4 2 1 嘛,那么直接把 最高位 的值 乘以 -1, 其他位都是正值,加起来就行了。
1 | 1 | 1 | 1 |
---|---|---|---|
-8 | 4 | 2 | 1 |
-8*1 + 4*1 + 2*1 + 1*1 = -1
比如 -3, -3 的补码 1101
1 | 1 | 0 | 1 |
---|---|---|---|
-8 | 4 | 2 | 1 |
-8*1 + 4*1 + 2*0 + 1*1 = -3