https://zhuanlan.zhihu.com/p/501536618
整数主要有三种表示方法:原码、反码、补码,目前的计算机都采用补码表示方法。各种表示方法的定义如下:
| 原码 | 第一位表示符号,剩余位表示数值 |
|---|---|
| 反码 | 正数的反码是其原码本身;负数的反码是在其原码的基础上,符号位不变,其余各位取反 |
| 补码 | 正数的补码就是其原码本身;负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后 +1(也即在反码的基础上 +1) |
举个例子,下面的表格展示了 -4 到 3 的三种表示方法:
| 数值 | 原码 | 反码 | 补码 |
| 3 | 011 | 011 | 011 |
| 2 | 010 | 010 | 010 |
| 1 | 001 | 001 | 001 |
| 0 | 000 | 000 | 000 |
| 100 | 111 | ||
| -1 | 101 | 110 | 111 |
| -2 | 110 | 101 | 110 |
| -3 | 111 | 100 | 101 |
| -4 | 100 |
三种编码方式对于整数是相同的,负数则是不同的。原码和反码的0有两种表示方法,补码中只有一种,因此,补码多出一个码用于表示-4。
计算机为什么选用补码表示整数呢?答案是使用补码,减法运算可以通过负数的加法运算来表示,处理器就不需要减法电路了。例如 B - A,可以通过加法运算 B + (-A) 来实现。
为什么补码能满足B-A通过B+(-A)来实现呢? B-A本质上就是B与A之间的距离,这就要求表示B(码)与A(码)之间的距离和B与A之间的距离是相同的。原码和反码因为各有两个码表示0,因此B(码)与A(码)之间的距离比B与A之间的距离大1,而补码就没有此问题。
我们用一套编码表示整数,只要这套编码的表现和十进制整数的表现一致即可。因此,我们可以用补码表示任意的整数区间,例如:[000,111]可以表示[-4,3]、[-2,5] 、[10,17] 、[0,7],只不过[-4,3][0,7]恰巧符合人类的习惯,被命名为有符号整数和无符号整数。
| 补码 | 有符号整数 | 自定义1 | 自定义2 | 无符号整数 |
| 011 | 3 | 5 | 13 | 3 |
| 010 | 2 | 4 | 12 | 2 |
| 001 | 1 | 3 | 11 | 1 |
| 000 | 0 | 2 | 10 | 0 |
| 111 | -1 | 1 | 17 | 7 |
| 110 | -2 | 0 | 16 | 6 |
| 101 | -3 | -1 | 15 | 5 |
| 100 | -4 | -2 | 14 | 4 |