Contents

为什么计算机需要补码?


三者的具体实例


关于这三者的定义就不讨论了, 给出 wiki链接 为了便于讨论, 先用4位二进制数表示一个整数, 接下来讨论下各种表示方法的此数的范围

注: 以下0000之类的二进制数都是未经变化的原码形式 exp: 原码无符号数1000表示8, 其原码有符号数1000表示-0, 其反码有符号数1111表示-7, 其补码有符号数00001表示-8. 希望读者自行动手将下面几种情况转化为相应的反码或补码, 然后对应十进制的范围, 以便更好的理解,

  1. 无符号数的原码: i. 从00001111依次表示十进制的015.
  2. 有符号数的原码: i. 从00000111依次表示十进制的07. ii. 从10001111依次表示十进制的-0-7.
  3. 有符号数的反码表示: i. 从00000111依次表示十进制的07. ii. 从10001111依次表示十进制的-7-0.
  4. 有符号数的补码表示: i. 从00000111依次表示十进制的07. ii. 从10001111依次表示十进制的-8-1.

分析反码和补码的意义


我们从原码的有符号数表示法出发, 可以看到, 存在以下两个缺陷 a. 正负相加并不等于$0$(根据二进制逢二进一): $0001+1001 = 1010$, 按照十进制就是$1 + (-1) = -2 \neq 0$. 明显存在问题 b. 有着0-0两个零存在. 也是不合理的 i. 首先来解决缺陷a: 如果对1001除符号位的各位取反, 即1110. 有$ 0001 + 1110 = 1111$, 即-0. (对-0困惑的话可以看上面的第三种情况). 虽然解决了二进制相加不为零的情况, 但是-0的情况依旧没有解决. ii. 接下来我们来解决缺陷b: 如果对负数都在末位加1, 比如十进制的-1表示成二进制1001再从反码1110到补码1111. 回到二进制原码从00001111, 由于负数部分都会进1, 比如1001表示-1, 其反码为1110表示-7, 其补码为1111, 表示-9. 所以其负数范围会变成-1-8(注意, 其原码和反码的负数范围都是-0-8). 所以这样就自然而然的解决了缺陷b. iii. 最后, 必须记得回去检查下这种补码的形式会不会有缺陷a, 如果为了解决缺陷b又产生了缺陷 a 可就麻烦了. 还是用到上面那个例子, -1的补码为1111, 1的补码依然为0001, $ 1111 + 0001 = 0000 $. 可喜可贺, 两个缺陷都完善好了(如有进位疑惑也可参照章末注释1).


  1. 这里之所以0000, 而不是10000, 是因为补码是计算机对二进制的普遍表示方法, 而计算机中运算器的位长是固定的(定长运算),上述运算中产生的最高位进位1将丢掉,所以结果依然为4位二进制数0000↩︎