掰扯一下补码2
上一次我们了解了补数,缩减基数补数以及其实现减法的原理。想要了解计算机是如何用加法运算来代替减法运算的。还需要继续往下了解一下负数在计算机中是如何表示的。
上一次介绍的用补数实现减法运算的第二种方法,存在当y大于x时,结果是错误的问题,例如123-456=123+543+1=667。这显然不对。
要解决这个问题,就必须引入负数的表示方法。在10为基数,位数为三的情况下,可以表示的正数是0到999,但也可以表示
-500到499。这样,667可以是-333(1000-667),就是正确答案了。
下面的图来帮助理解这种表达方式,把数轴的直线连城圆,当然是有限个数的轴,比如三位数。在负数的表达方式中,负数的绝对值加上其表示的正数就等于b的n次方。|-1| + 999 = 1000,|-500| + 500 =
1000。这种方法可以称之为环形表示吧。
计算机的负数表示方式--2补数
计算机是2进制的,实现上有几种表示负数的方法,目前广泛采用的就是2补码。
必须先介绍一下1补数的实现。以最高位为符号位,1代表负数,所有负数都是其对应正数的每一位取反。例如八位二进制数,1000 0000 可以由其对应正数0111 1111每一位取反得到,其表示的是-127。这种方法有一个问题,就是1111 1111表示的是-0,和0000 0000 加起来整个系统中有两个0。下表来自维基百科,可以帮助大家理解这种表示方法。
2进制数 | 1补数数 | 无符号数 |
---|---|---|
00000000 | +0 | 0 |
00000001 | 1 | 1 |
⋮ | ⋮ | ⋮ |
01111101 | 125 | 125 |
01111110 | 126 | 126 |
01111111 | 127 | 127 |
10000000 | −127 | 128 |
10000001 | −126 | 129 |
10000010 | −125 | 130 |
⋮ | ⋮ | ⋮ |
11111101 | −2 | 253 |
11111110 | −1 | 254 |
11111111 | −0 | 255 |
2补数可以解决这个问题。2补数是在1补数的基础上,取反后再加1。于是1111 1111表示的是-1,因为1的二进制取反为1111 1110,加1后得到1111 1111。其中-128为1000 0000取反后为0111 1111,加1后得到
1000 0000。这种方法和上面介绍的环形表示法的方式一致。
2进制数 | 2补码数 | 无符号数 |
---|---|---|
00000000 | 0 | 0 |
00000001 | 1 | 1 |
⋮ | ⋮ | ⋮ |
01111110 | 126 | 126 |
01111111 | 127 | 127 |
10000000 | −128 | 128 |
10000001 | −127 | 129 |
10000010 | −126 | 130 |
⋮ | ⋮ | ⋮ |
11111110 | −2 | 254 |
11111111 | −1 | 255 |
可以发现在2进制数中,取反就相当于缩减基数补数啊。2补数又在此基础上加了1,这就和之前介绍的补数的减法计算的第二种方法一致。如0111 1111 + 1000 0000 = ?
本人水平有限,但是欢迎指正交流。
如果你觉得有点意思,欢迎关注 悟空的小车库。