补码引入
举一个生活化的例子
假设由一个挂钟,它只能顺时钟调时间,那么它调时间就分成了一下两种情况
- 正好顺时针调就能调好 如:时针从5调到9
- 需要逆时针调才能调好 如:时针从10调到7
在上面的情况中1是不用处理的,2我们可以下意识的想到顺时针转过12后再转到7.
诶,这就是计算机补码的思想,我们再用更详细的过程推到一下。
上面的10逆时针调到7记为 10 - 3 = 7
那么10顺时针调到7就是 10 + 2 = 12 再加 7 也就是加了9
原来10 - 3 在 表盘里与 10 + 9 是相等的,为什么?
这就要引入模运算了
取模就是取余数运算符为mod,如5 mod 2 = 1,也就是5 / 2 余 1
我们就可以发现
(10 - 3) mod 12 = 7 mod 12 = 7
(10 + 9) mod 12 = 19 mod 12 = 7
原来是 7 和 19 除以 12 的余数是相同的才有这样的结果
那么这个 9 也就是 -3 在这种情况下的补码
那么这个9是怎么的出来的呢?
( 10 − 3 ) m o d 12 = [ ( 10 m o d 12 ) − ( 3 m o d 12 ) ] m o d 12 = [ ( 10 m o d 12 ) + ( 12 m o d 12 ) − ( 3 m o d 12 ) ] m o d 12 = ( 10 + 12 − 3 ) m o d 12 (10 - 3) mod 12 \\ = [(10 mod 12) - (3 mod 12)] mod 12 \\ = [(10 mod 12) + (12 mod 12) - (3 mod 12)] mod 12 \\ = (10 + 12 - 3) mod 12 (10−3)mod12=[(10mod12)−(3mod12)]mod12=[(10mod12)+(12mod12)−(3mod12)]mod12=(10+12−3)mod12
原来是用12 - 3算出来的9
我们讲表盘中的数字列举出来
1 2 3 4 5 6 7 8 9 10 11 12
在将12换成0
0 1 2 3 4 5 6 7 8 9 10 11
这个12 就是这一串数字所能表达的最大数加一
那么补码 = 能表示的最大数加一 - 减数
补码
让我们根据上面的例子,将计算变成二进制的形式
假设有8为二进制数
能表示最大的数就是11111111
加一后就是100000000
如果要求出 -1010 的补码 绝对值就是00001010(因为上面是减去的3而不是-3)
就用100000000 - 00001010 = 11110110
所以 11110110 就是 -1010 的补码
验算:用10000 - 1010
00010000 - 00001010 = 00000110
00010000 + 11110110 = 100000110 = 00000110
总结更一般的公式
[ − x ] 补 = 2 n − x [-x]_补=2^n-x [−x]补=2n−x
我们会发现用
11111111 - 00001010 = 11110101
正好是00001010的取反
而
11111111 = 2 n − 1 11111111=2^n-1 11111111=2n−1
所以
( 2 n − 1 ) − x + 1 = 2 n − 1 (2^n-1)-x+1=2^n-1 (2n−1)−x+1=2n−1
所以补码还可以这样算
[ − x ] 补 = [ x ] 反 + 1 [-x]_补=[x]_反+1 [−x]补=[x]反+1
如:
[ − 1010 ] 补 = [ 00001010 ] 反 + 1 11110101 + 1 = 11110110 [-1010]_补=[00001010]_反+1 \\ 11110101+1=11110110 [−1010]补=[00001010]反+111110101+1=11110110