计算机用二进制来表示数据,先看一下原码、反码和补码的计算方式:
- 原码:最高位为符号位,剩余位(数据位)为x的绝对值。
- 反码:如果x为正数,则与原码相同;如果x为负数,符号位保持不变,数据位取反。
- 补码:如果x为正数,则与原码相同;如果x为负数,符号位保持不变,数据位取反,然后加1(若符号位有进位,则舍弃进位)。
计算机为什么用补码存储数据。简单起见,以4位存储表示有符号数为例,通过原码、反码和补码的表示法来生成一张表:
| 有符号数(十进制) | 原码 | 反码 | 补码 |
|---|---|---|---|
| +7 | 0111 | 同原码 | 同原码 |
| +6 | 0110 | 同原码 | 同原码 |
| +5 | 0101 | 同原码 | 同原码 |
| +4 | 0100 | 同原码 | 同原码 |
| +3 | 0011 | 同原码 | 同原码 |
| +2 | 0010 | 同原码 | 同原码 |
| +1 | 0001 | 同原码 | 同原码 |
| +0 | 0000 | 同原码 | 同原码 |
| -0 | 1000 | 1111 | 0000 |
| -1 | 1001 | 1110 | 1111 |
| -2 | 1010 | 1101 | 1110 |
| -3 | 1011 | 1100 | 1101 |
| -4 | 1100 | 1011 | 1100 |
| -5 | 1101 | 1010 | 1011 |
| -6 | 1110 | 1001 | 1010 |
| -7 | 1111 | 1000 | 1001 |
| -8 | 超出4bit能表达范围 | 超出4bit能表达范围 | 1000 |
通过上述表格,可以很自然的总结出一个结论:补码表示法(two's complement representation)可以防止0的机器数重码,同时又解决了原码和反码无法表示-8的问题,这样就极大的简化了计算机的硬件设计。
-0 的补码的求解过程:
[x]补 = 2^n - \x\ = 2^4 - -0\ = 2^4 - (+0),使用二进制则为10000 - 0000 = 10000,超过4位(有进位),那么舍弃进位1,最终结果就是0000)