整数表示
众所周知, 数据在计算机里是由二进制存储的, 所以在表示整数, 尤其是负数的时候, 需要编码, 因为计算机不能直接写一个负号. 编码可以理解为一个可逆函数, 输入是数学定义下的数字(也叫 真值), 输出是该数字在计算机中的表示.
无符号整数
无符号编码很简单, 就是二进制表示, 然后存在计算机中. 因为没有负号, 只能表示非负数.
$\vec x$ 表示 $w$ 位的机器码 0-1 向量, $\vec x_i \in {0, 1}$ 表示其二进制第 $i$ 位上的取值, $x$ 表示真值, 那么:
$$x = \sum_{i=0}^{w-1} \vec x_i \cdot 2^i$$
有符号整数
原码
原码 把最高位当成符号位, 正数的最高位为 0
, 负数的最高位为 1
. 然后就出现了 $0$ 有两种表示, 为区别, 称为 $+0$ 和 $-0$.
$$x = (-1)^{\vec x_{w-1}} \sum_{i=0}^{w-2} \vec x_i \cdot 2^i$$
补码
补码 类似于取模的操作, 比如在模 $2^{32}$ 意义下, $-1 \equiv 2^{32} - 1 \equiv (\overbrace{111\dots1}^{31\text{个}1})_2 \mod 2^{32}$. 这样的好处是减法统一到了加法, 不用去处理符号位. 这也是大部分机器对整数表示方式.
$$x = -2^{w-1} \cdot x_{w-1} + \sum_{i=0}^{w-2} \vec x_{i} \cdot 2^i$$
从上面这个式子可以看出, 最高位的 “权值” 为 $-2^{w-1}$, 而不是 $2^{w-1}$
反码
反码 大概率是中文意译过来的. 他对负数的编码是这样的: 最高位为符号位, (负数)设为 1
, 然后他的绝对值 $|x|$ 按照二进制存在其他位上, 然后把这些位都取反.
$$x = -(2^{w-1}-1) \cdot 2^{w-1} + \sum_{i=0}^{w-2} \vec x_{i} \cdot 2^i$$
可以看到, 最高位的 “权值” 为 $-(2^{w-1}-1)$, 而不是 $-2^{w-1}$