我们采用十进制,机器采用二进制。十进制与二进制可以相互转换,十进制的 0-255 与二进制的 00000000-11111111 对应。

但是现在出现个问题:我们的十进制是有负数的,那如何在机器中使用二进制表示负数呢?

对于这个问题,有以下几种方案:

原码(Original code)

将最高位视为符号位,即正数该位为 0,负数该位为 1(此时零有两种表示:+0 和 -0)
其余位表示数值的大小。

原码表示法示例:
00000010 = +2,00000011 = +3
10000010 = -2,10000011 = -3

使用原码的优点:
1)简单直观
比如 +11 的原码为 00001011,-11 的原码就是 10001011,只需修改首位。

使用原码的缺点:
1)无法直接参与计算
例如 (+11) + (-11) = 0,但是 (00001011) + (10001011) != 0,如要处理这个问题,则硬件需要特殊设计,这就增加复杂性。

反码(Inverse code)

正数的反码是:与原码相同;
负数的反码是:对正数的原码逐位取反;(或者对负数的原码逐位取反,但最高位为壹;)

反码表示法示例:
+12 的反码为 00001100
-12 的反码为 11110011

使用反码的缺点:
1)无法直接参与计算
例如:3 是正数,原码为 0011,反码为 0011;-3 原码是 1011,-3 反码是 1100;两数相加,依旧无法得零;

补码(Complement code)

正数的补码是:与原码相同;
负数的补码是:对正数的原码逐位取反,再加壹

补码表示法示例:
+12 的补码为 00001100
-12 的补码为 11110100

使用补码的优点:
1)将符号位和数值域统一处理
2)加法和减法也可以统一处理

附加说明

这是种负数的表示法,而不是说补码 10000001 通过进制转化可以得到 -127,我们只是定义 -127 在计算机中用 10000001 来表示。

参考文献

On the Primitive Code, Inverse Code, Complement Code and Shift Code of Operating System
百度百科/补码