反码

来自GSXAB的知识库
反码
术语名称 反码
英语名称 ones' complement

反码(ones' complement)是一种计算机内的有符号整数表示方法(机器数)。在反码中 [math]\displaystyle{ n }[/math]二进制位中的最高位(most significant bit, MSB)被留作符号位(sign bit),剩下的 [math]\displaystyle{ (n-1) }[/math] 位用于容纳包含 0 在内的各 [math]\displaystyle{ 2^{n-1} }[/math] 个数,并使用绝对值二进制表示,若符号位为 - ,将绝对值部分按位取反

定义

反码(ones' complement)指用 [math]\displaystyle{ n }[/math] 位二进制位构成的机器数表示有符号数的方法,其中将其最高位留作符号位,剩余 [math]\displaystyle{ (n-1) }[/math] 位作为绝对值部分:

  • 符号位取 0 时表示符号为 + ,符号位取 1 时表示符号为 - 。
  • 绝对值部分取值取反表示数的绝对值。若绝对值为 [math]\displaystyle{ x }[/math] 则表示为 [math]\displaystyle{ 2^{n-1}-1-x }[/math]

由于符号位作为二进制数的一部分也可以看成是 [math]\displaystyle{ +2^{n-1} }[/math] ,也可以表述为对任意 [math]\displaystyle{ x }[/math] ,其表示为 [math]\displaystyle{ \begin{cases}x&, x\geq 0\\ 2^n-1+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{ -0 }[/math][math]\displaystyle{ -(2^{n-1}-1) }[/math]

注意:反码表示中,存在 [math]\displaystyle{ 0;00\cdots0 }[/math][math]\displaystyle{ 1;11\cdots1 }[/math] 两个机器数,其真值分别是 [math]\displaystyle{ +0 }[/math][math]\displaystyle{ -0 }[/math] 。因此, [math]\displaystyle{ 2^n }[/math] 个数所对应的真值只有 [math]\displaystyle{ (2^n-1) }[/math] 个不同的,真值范围为 [math]\displaystyle{ -(2^{n-1}-1), \cdots, 2^{n-1}-1 }[/math]

反码运算

将机器数表示本身视为二进制数,则可以认为从数本身到反码的映射关系为:

[math]\displaystyle{ x \mapsto \begin{cases} x &, x \geq 0 \\ (2^{n-1}-1-x)+2^{n-1} = 2^n-1-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] 减去原数,这个数与上式中的被减数相同。也就是说, [math]\displaystyle{ -x }[/math] 的反码表示就是 [math]\displaystyle{ x }[/math] 的反码表示按位取反。

反码加减法

+ [math]\displaystyle{ b\geq 0, b'=b }[/math] [math]\displaystyle{ b\lt 0, b'=2^n-1+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-1) &,a+b\geq 0 \\ a'+b' &,a+b\lt 0 \end{cases} }[/math]
[math]\displaystyle{ a\lt 0, a'=2^n-1+a }[/math] [math]\displaystyle{ (a+b)'=\begin{cases} a'+b'-(2^n-1) &,a+b\geq 0 \\ a'+b' &,a+b\lt 0 \end{cases} }[/math] [math]\displaystyle{ (a+b)'=2^n-1+a+b=a'+b'-(2^n-1) }[/math]

不考虑两数相加时超过表达上限的情况(即数字溢出),分析数字和的表示与两个数字的分别表示关系如上表。 可以看到,如果没有超过上限,所有的位上都可以通过直接相加,并适当地减去 [math]\displaystyle{ 2^n-1 }[/math] 以保证表示落在范围内,以达到实际的表示。 考虑到表示中 [math]\displaystyle{ 2^n }[/math] 刚好是进行加法时最高位溢出到了更前方,无法保存这一位,就是自动执行了 [math]\displaystyle{ -2^n }[/math] ,也就是说,溢出到无法表示的位时再进行 [math]\displaystyle{ +1 }[/math] 就可以得到正确的表示。 也就是说,在最高位溢出一个 1 时向最低位 +1 ,就好像最高位被进位到最低位了一样似的,这种进位规则,称为循环进位(end-around carry)。

因此,反码加法就是其机器数作为二进制数时,带有循环进位的加法。

同样,在进行减法时,除了取反并相加外也可以通过机器数相减,而且当最高位不够减需要借位时,也需要再往前一位补上 1 以后,在最低位 -1 。也相当于从最低位借位,这种规则称为循环借位(end-around borrow)。

反码减法就是其机器数作为二进制数时,带有循环借位的减法。


数的内部表示
十进制数的二进制编码 BCDGray 码奇偶校验码 、 字符表示
有符号整数的机器数 原码反码补码移码
有符号小数的机器数 定点数浮点数IEEE 754