补码

    以8位的数据为例,对于无符号数来说是从00000000b ~ 11111111 b 到0 ~ 255一一对应的。那么我们如何对有符号数进行编码呢?即我们如何用8位数据表示有符号数呢?
    既然表示的数有符号,则必须要能够区分正、负。
    首先,我们可以考虑用8位数据的最高位来表示符号,1表示负,0表示正,而用其他位表示数值。如下:

00000000 b :0
00000001 b :1
00000010 b :2
01111111 b :127
10000000 b :?
10000001 b :–1
10000010 b :–2
11111111 b :–127

    可见,用上面的表示方法,8位数据可以表示–127 ~ 127的254个有符号数。从这里我们看出一些问题,8位数据可以表示255种不同的信息,也就是说应该可以表示255个有符号数,可用上面的方法,只能表示254个有符号数。注意,用上面的方法,00000000 b和10000000 b都表示0,一个是0,一个是 – 0 ,当然不可能有 – 0 。可以看出,这种表示有符号数的方法是有问题的,它并不能正确地表示有符号数。
    我们再考虑用反码来表示,这种思想是,我们先确定用00000000 b ~ 0111111l b 表示 0~ 127,然后再用它们按位取反后的数据表示负数。如下:

00000000 b :0                      11111111 b :?
00000001 b :1                      11111110 b :–1
00000010 b :2                      11111101 b :–2
01111111 b :127                  10000000 b :–127

    可以看出,用反码表示有符号数存在同样的问题,0出现重码。
    为了解决这种问题,采用一种称为补码的编码方法。这种思想是:先确定用00000000 b ~ 01111111 b 表示 0~ 127,然后再用它们按位取反加 1 后的数据表示负数。如下:

00000000 b :0                      11111111 b + 1= 00000000 b :0
00000001 b :1                      11111110 b + 1= 11111111 b :–1
00000010 b :2                      11111101 b + 1= 11111110 b :–2
01111111 b :127                  10000000 b + 1= 10000001 b :–127

观察上面的数据,我们可以发现,补码方案中:
(1)最高位为1 ,表示负数;
(2)正数的补码取反加 1 后,为其对应的负数的补码负数的补码取反加 1 后,为其绝对值比如:
1 的补码为:00000001b ,取反加 1 后为:11111111 b,表示–1;负数的补码,符号位不变其它位按位取反后加1
–1的补码为:11111111 b ,取反加 1 后为:00000001 b ,其绝对值为 1 。


    我们从一个负数的补码不太容易看出它所表示的数据,比如:11010101 b 表示的数据是多少?但是我们利用补码的特性,将11010101 b 取反加 1 后为:00101011 b。可知11010101 b 表示的负数的绝对值为:2BH ,则11010101 b 表示的负数为 –2BH 。
    那么–20 的补码是多少呢?用补码的特性,–20 的绝对值是20 , 00010100 b ,将其取反加1 后为:11101100 b 。可知 –20H 的补码为:11101100 b 。


那么 10000000b 表示多少呢?10000000b 取反加 1 后为:10000000 b ,其大小为128,所以10000000b 表示 –128 。8位补码所表示的数的范围:–128 ~ 127
补码为有符号数的运算提供了方便,运算后的结果依旧满足补码规则。
比如:
计算            补码表示
10               00001010 b
+ (–20)       11101100 b
–10             11110110 b

原文地址:https://www.cnblogs.com/meihao1203/p/7930949.html