为什么计算机需要补码?
三者的具体实例
关于这三者的定义就不讨论了, 给出 wiki链接 为了便于讨论, 先用4位二进制数表示一个整数, 接下来讨论下各种表示方法的此数的范围
注: 以下0000
之类的二进制数都是未经变化的原码形式
exp: 原码无符号数1000
表示8
, 其原码有符号数1000
表示-0
, 其反码有符号数1111
表示-7
, 其补码有符号数0000
1表示-8
.
希望读者自行动手将下面几种情况转化为相应的反码或补码, 然后对应十进制的范围, 以便更好的理解,
- 无符号数的原码:
i. 从
0000
到1111
依次表示十进制的0
到15
. - 有符号数的原码:
i. 从
0000
到0111
依次表示十进制的0
到7
. ii. 从1000
到1111
依次表示十进制的-0
到-7
. - 有符号数的反码表示:
i. 从
0000
到0111
依次表示十进制的0
到7
. ii. 从1000
到1111
依次表示十进制的-7
到-0
. - 有符号数的补码表示:
i. 从
0000
到0111
依次表示十进制的0
到7
. ii. 从1000
到1111
依次表示十进制的-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
. 回到二进制原码从0000
到1111
, 由于负数部分都会进1, 比如1001
表示-1
, 其反码为1110
表示-7
, 其补码为1111
, 表示-9
. 所以其负数范围会变成-1
至-8
(注意, 其原码和反码的负数范围都是-0
到-8
). 所以这样就自然而然的解决了缺陷b
.
iii. 最后, 必须记得回去检查下这种补码的形式会不会有缺陷a
, 如果为了解决缺陷b
又产生了缺陷 a
可就麻烦了. 还是用到上面那个例子, -1
的补码为1111
, 1
的补码依然为0001
, $ 1111 + 0001 = 0000 $. 可喜可贺, 两个缺陷都完善好了(如有进位疑惑也可参照章末注释1).
-
这里之所以
0000
, 而不是10000
, 是因为补码是计算机对二进制的普遍表示方法, 而计算机中运算器的位长是固定的(定长运算),上述运算中产生的最高位进位1
将丢掉,所以结果依然为4位二进制数0000
. ↩︎