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 |