# 二进制下的补码、反码、原码——适用于有符号整数

## 简单定义
简单起见，我们这里只考虑三位二进制数所能表示的范围，即$[-4, -3, -2, -1, 0,\ 1,\ 2,\ 3]$。
## 机器数和真值
一个数在计算机中的二进制表现形式，就是这个数的**机器数**（相当于数的**原码**）。
例如，$-3$ 的机器数即为 $111$，$2$ 的机器数为 $010$。

机器数在考虑最高位为符号位的情况下，换算出来的值就是**真值**，例如 $111$ 的真值为 $-3$，而形式值为 $7$；$010$ 的形式值和真值都为 $2$。

## 原码、反码、补码
有符号整数的**原码**就是它的**机器数**，正数的反码**与原码相同**，而负数的反码则是**符号位不变，其余位取反**。

正数的补码（Complement）不变，负数的补码则是它的**反码 $+1$**，例如 $-1$ 的反码为 $110$，补码为 $111$；也可以说负数的**补码**是该负数的相反数的原码取反 $+1$。

## 为什么要用补码？

使用补码可以解决减法运算的问题。
例如 $2 - 1 = 2 + (-1) = 010 + 111 = 001 = 1$ （$1001$ 去掉超出的最高位）。

使用原码或者反码都不好处理这个问题。

## 为什么补码会有这个效果？
我们首先要意识到一点，$-1$ 的补码为 $111$，$111$ 对应的形式值为 $7$，而 $7 - (-1) = 8$。

例如，当我们使用 $2 - 1$ 时，相当于 $2 + 7 = 9$，然而，由于我们只能表示 $-4 \sim 3$ 这个范围内的所有数，大于 3 的数，就变成了 $9\mod 8 = 1$。

或者我们可以从循环的角度考虑：$[-4, -3, -2, -1,\ 0, \ 1,\ 2,\ 3,-4,-3,-2,-1,\ 0,\ 1,\ 2,\ 3]$，正好循环到 $1$。

从数学的角度，$-1$ 与 $7$ 对 $8$ 同余，那么：

$(2 + -1)\mod\ 8 = (2\mod 8)\ +\ ((-1)\mod 8)\ =\ (2\mod8)\ +\ (7\mod 8)\ =\ (2+7)\mod 8\ =\ 1$。（$8$ 对应开始提到的用三位二进制表示）。

注意：$-4$ 没有原码和反码表示，补码为 $100$。（可以理解为由 $011 + 1$ 得到）。






