补码
补码 | |
---|---|
术语名称 | 补码 |
英语名称 | two's complement |
别名 | 2's complement |
补码(two's complement)是一种计算机内的有符号整数表示方法(机器数)。在补码中 [math]\displaystyle{ n }[/math] 位二进制位中的最高位(most significant bit, MSB)被留作符号位(sign bit),剩下的 [math]\displaystyle{ (n-1) }[/math] 位用于容纳包含 0 在内的各 [math]\displaystyle{ 2^{n-1} }[/math] 个数,并使用绝对值的二进制表示,若符号位为 - ,将绝对值减一再按位取反。
由于在四种有符号整数的表达中运算最为简洁,是最常见的有符号整数表示。
定义
补码(two's complement)指用 [math]\displaystyle{ n }[/math] 位二进制位构成的机器数表示有符号数的方法,其中将其最高位留作符号位,剩余 [math]\displaystyle{ (n-1) }[/math] 位作为绝对值部分:
- 符号位取 0 时表示符号为 + ,符号位取 1 时表示符号为 - 。
- 绝对值部分取值取反加一表示数的绝对值。若绝对值为 [math]\displaystyle{ x }[/math] 则表示为 [math]\displaystyle{ 2^{n-1}-x }[/math] 。
由于符号位作为二进制数的一部分也可以看成是 [math]\displaystyle{ +2^{n-1} }[/math] ,也可以表述为对任意 [math]\displaystyle{ x }[/math] ,其表示为 [math]\displaystyle{ \begin{cases}x&, x\geq 0\\ 2^n+x &, x\lt 0 \end{cases} }[/math] 。
具体对应:
- [math]\displaystyle{ 0;00\cdots0 }[/math] 到 [math]\displaystyle{ 0;11\cdots1 }[/math] 对应 [math]\displaystyle{ +0 }[/math] 到 [math]\displaystyle{ +2^{n-1}-1 }[/math] 。
- [math]\displaystyle{ 1;11\cdots1 }[/math] 到 [math]\displaystyle{ 0;00\cdots0 }[/math] 对应 [math]\displaystyle{ -1 }[/math] 到 [math]\displaystyle{ -2^{n-1} }[/math] 。
注意: [math]\displaystyle{ 2^n }[/math] 个数所对应的真值有 [math]\displaystyle{ 2^n }[/math] 个不同的,真值范围为 [math]\displaystyle{ -2^{n-1}, \cdots, 2^{n-1}-1 }[/math] 。需要注意的是 [math]\displaystyle{ -2^{n-1} }[/math] 在范围内,而 [math]\displaystyle{ 2^{n-1} }[/math] 则不在。
补码运算
将机器数表示本身视为二进制数,则可以认为从数本身到机器数的映射关系为:
[math]\displaystyle{ x \mapsto \begin{cases} x &, x \geq 0 \\ (2^{n-1}-1-x)+2^{n-1} = 2^n+x &, x \leq 0 \\ \end{cases} }[/math]
补码相反数
由于对二进制数 [math]\displaystyle{ a_{n-1} a_{n-2} \cdots a_1 a_0 }[/math] 取反的 [math]\displaystyle{ \bar{a}_{n-1} \bar{a}_{n-2} \cdots \bar{a}_1 \bar{a}_0 }[/math] 会满足 [math]\displaystyle{ 1 - a_i = \bar{a}_i }[/math] ,实际上相当于用二进制数 [math]\displaystyle{ (11\cdots 11)_2 = 2^n-1 }[/math] 减去原数,这个数与上式中的被减数相差 1 。也就是说, [math]\displaystyle{ -x }[/math] 的反码表示就是 [math]\displaystyle{ x }[/math] 的反码表示按位取反再加一。
反码加减法
+ | [math]\displaystyle{ b\geq 0, b'=b }[/math] | [math]\displaystyle{ b\lt 0, b'=2^n+b }[/math] |
---|---|---|
[math]\displaystyle{ a\geq 0, a'=a }[/math] | [math]\displaystyle{ (a+b)'=a+b=a'+b' }[/math] | [math]\displaystyle{ (a+b)'=\begin{cases} a'+b'-2^n &,a+b\geq 0 \\ a'+b' &,a+b\lt 0 \end{cases} }[/math] |
[math]\displaystyle{ a\lt 0, a'=2^n+a }[/math] | [math]\displaystyle{ (a+b)'=\begin{cases} a'+b'-2^n &,a+b\geq 0 \\ a'+b' &,a+b\lt 0 \end{cases} }[/math] | [math]\displaystyle{ (a+b)'=2^n+a+b=a'+b'-2^n }[/math] |
不考虑两数相加时超过表达上限的情况(即数字溢出),分析数字和的表示与两个数字的分别表示关系如上表。 可以看到,如果没有超过上限,所有的位上都可以通过直接相加,并适当地减去 [math]\displaystyle{ 2^n }[/math] 以保证表示落在范围内,以达到实际的表示。 考虑到表示中 [math]\displaystyle{ 2^n }[/math] 刚好是进行加法时最高位溢出到了更前方,无法保存这一位,就是自动执行了 [math]\displaystyle{ -2^n }[/math] ,也就是说,只要抛弃溢出位,就能得到正确的表示。
因此,补码加法就是其机器数作为二进制数时,抛弃溢出位进位的加法。
同样,在进行减法时,除了取反加一再相加外也可以通过机器数相减,而且当最高位不够减需要借位时,也可以从前一位虚空补上一个 1 。
补码减法就是其机器数作为二进制数时,抛弃溢出位借位的减法。
数的内部表示 | |
---|---|
十进制数的二进制编码 | BCD 、 Gray 码 、 奇偶校验码 、 字符表示 |
有符号整数的机器数 | 原码、反码、补码、移码 |
有符号小数的机器数 | 定点数、浮点数(IEEE 754) |