现从简单的补码说起,
原码: 正数的原码就是它的本身, 负数用最高位是 1 表示负数
反码: 正数的反码就是原码, 负数的反码等于原码除符号位以外所有的位取反
补码: 正数的补码和原码一样, 负数的补码是负数的反码加 1
[符号位在计算时直接参与运算]
原码缺点: 0 有两种表示, 无法处理减法
反码: 可以处理加减法及符号位, 但 0 仍然有两种表示方式
补码: 完美解决以上问题
逐条分析
原码加减法运算: 略 (很显然除了两正数相加其他都算不了)
反码加减法运算:
我们将符号位与绝对值分开讨论 (数字形如 &&&&&&&&)
设一个负数为 - X, 则其反码表示的数为 -(128-x)
----- 正数 + 负数
现假设一个运算为 Y+(-X)[Y 为正数]
符号位运算为 0+1
绝对值运算为 Y+128-X
此时若 Y>=X 则溢出一位至符号位得符号位为 0, 同时绝对值位运算结果为 Y-X(>0), 再将结果取原码得到符号位为 0, 绝对值位 Y-X. 符合预期
此时若 Y<X 则, 将结果取原码的符号位为 1, 绝对值为 128-(Y+128-X)=X-Y, 符合预期
----- 负数 + 负数
现假设一个运算为 (-X1)+(-X2)
符号位运算为 1+1=0
绝对值位运算为 (256-X1-X2)
此时若 X1+X2>128 则将结果取原码的绝对值位 X1+X2-128, 符号位为 0. 显然得到的答案不正确, 但此类情况对应着溢出情况. 所以结果也符合预期
此时若 X1+X2<=128 则绝对值位溢出一位至符号位得符号位为 1, 绝对值位为 128-X-Y. 符合预期
综上, 反码运算解决了符号位问题.
但 0 仍然有 00000000 和 10000000 两种表示方法
补码
1, 先解释 -- 减一个数等同于加其的补码
设一个负数的原码为 X, 反码为 Y, 补码为 Z 则
- X+Y=11111111
- Z=Y+1
的 X+Z=100000000(1 溢出)=00000000
故 X=-Z
所以说采用补码, 统一了加减法
2, 再解释补码的加减运算
略 (同反码类似)
来源: http://www.bubuko.com/infodetail-2946376.html