补码系统计算一致性的数学推导

补码系统设计了一套机制,将数学上的有符号整数范围 \([-2^{n-1}, 2^{n-1} - 1]\) 映射到无符号整数范围 \([0, 2^n - 1]\)。映射后,映射后,所有的算术运算(加法、减法等)在无符号二进制运算下,结果等价于有符号整数的数学运算。

补码的核心是设计一种“编码”,让负数、正数在二进制世界里用统一的规则运算,结果和数学一致。

在这种映射规则下,对于正数和零(\(x \geq 0\)),直接用二进制表示,最高位为 0,即\(B(x) = x\),范围:\([0, 2^{n-1} - 1]\)。对于负数(\(x < 0\)),负数 \(-x\)(其中 \(x > 0\))映射为:\(B(-x) = 2^n - x\),范围:\([-2^{n-1}, -1]\),整个范围正好覆盖 \([0, 2^n - 1]\),共 \(2^n\) 个值,无浪费。

对于任意有符号整数 \(k \in [-2^{n-1}, 2^{n-1} - 1]\)

如果 \(k \geq 0\)\[ B(k) = k \] 如果 \(k < 0\)\[ B(k) = 2^n + k \] 因为 \(k = -x\)\(x > 0\)),所以: \[ B(-x) = 2^n - x = 2^n + (-x) \] 这一映射确保:

  1. 每个有符号整数 \(k\) 对应唯一的无符号值 \(B(k) \in [0, 2^n - 1]\)

  2. 反过来,每个无符号值 \(u \in [0, 2^n - 1]\) 对应一个有符号整数。

补码的映射不仅覆盖了范围,还保证了运算(特别是加法、减法)在无符号二进制下的结果与有符号整数的数学运算一致。

对于有符号整数加法,有\(x + (-x) = 0\),在补码系统中,正数被设计为\(B(x) = x\),负数被设计为\(B(-x) = 2^n - x\),相加: \[ B(x) + B(-x) = x + (2^n - x) = 2^n \]\(n\) 位硬件中,\(2^n = 1 0000 ... 0000\)(第 \(n+1\) 位为 1),寄存器只保留低 \(n\) 位:\(0000 ... 0000 = 0\)。从模 \(2^n\) 视角看: \[ 2^n \equiv 0 \pmod{2^n} \] 所以: \[ x + (2^n - x) \equiv 0 \pmod{2^n} \] 对于任意任意 \(a, b \in [-2^{n-1}, 2^{n-1} - 1]\),计算 \(a + b\),结果 \(s\),补码映射: \[ B(a) + B(b) \mod 2^n = B(s) \] 如果 \(s\) 在范围内,结果正确;如果溢出,模 \(2^n\) 保证循环性。

对于减法,可以转为加法,\(a - b = a + (-b)\)\(B(-b) = 2^n - b\)

硬件用加法器: \[ B(a) + B(-b) = a + (2^n - b) \]\(2^n\) 后得到正确结果。

要保证循环性(溢出处理),补码形成模 \(2^n\) 的圆环,最大正数:\(2^{n-1} - 1 = 0111 ... 1111\),加 1: \[ 2^{n-1} - 1 + 1 = 2^{n-1} = 2^n - 2^{n-1} = B(-2^{n-1}) \] 最小负数:\(-2^{n-1} = 1000 ... 0000\),减 1: \[ 2^n - 2^{n-1} - 1 = 2^{n-1} - 1 \] 溢出时,数值在 \([-2^{n-1}, 2^{n-1} - 1]\) 内循环,硬件无需额外处理。

推导 \(B(a) + B(b) \mod 2^n\) 如何映射到 \(B(a + b)\)

对于任意 \(a\)\[ B(a) = \begin{cases} a & \text{if } a \geq 0 \\ 2^n + a & \text{if } a < 0 \end{cases} \] 同理,\(B(b)\) 类似。

计算 \(B(a) + B(b)\),结果模 \(2^n\)\[ S = (B(a) + B(b)) \mod 2^n \] \(S\)\(n\) 位寄存器的输出,范围 \([0, 2^n - 1]\)

需要证明:

  1. 如果 \(a + b \in [-2^{n-1}, 2^{n-1} - 1]\)(无溢出),则:\(S = B(a + b)\)

  2. 如果 \(a + b\) 溢出(超出范围),则 \(S\) 是模 \(2^n\) 下的正确映射。

假设 \(a + b = s\)(数学和)。

情况 1:\(a \geq 0, b \geq 0\)(正数 + 正数)

补码: \[ B(a) = a, \quad B(b) = b \] 硬件加法: \[ B(a) + B(b) = a + b \] 结果: \[ S = (a + b) \mod 2^n \] 无溢出。如果 \(a + b \leq 2^{n-1} - 1\)(在范围内):\(S = a + b = B(a + b)\)

正溢出。如果 \(a + b > 2^{n-1} - 1\)(超出正数范围):\(S = (a + b) \mod 2^n\)。在补码中,这对应负数(圆环循环)。

情况 2:\(a < 0, b < 0\)(负数 + 负数)

补码: \[ B(a) = 2^n + a, \quad B(b) = 2^n + b \] 硬件加法: \[ B(a) + B(b) = (2^n + a) + (2^n + b) = 2^{n+1} + (a + b) \] 结果: \[ S = (2^{n+1} + (a + b)) \mod 2^n \] 因为 \(2^{n+1} = 2 \cdot 2^n \equiv 0 \pmod{2^n}\)(因为 \(2^n \mod 2^n = 0\)),所以,\(S = (a + b) \mod 2^n\)

无溢出。如果 \(-2^{n-1} \leq a + b < 0\)\(S = 2^n + (a + b) = B(a + b)\)

负溢出。如果 \(a + b < -2^{n-1}\)\(a + b\) 是负数,模 \(2^n\) 后:\(S = 2^n + (a + b)\),可能映射到正数(圆环循环)。

情况 3:\(a \geq 0, b < 0\)(正数 + 负数)

补码: \[ B(a) = a, \quad B(b) = 2^n + b \] 硬件加法: \[ B(a) + B(b) = a + (2^n + b) = 2^n + (a + b) \] 结果: \[ S = (2^n + (a + b)) \mod 2^n = (a + b) \mod 2^n \] 无溢出。如果 \(-2^{n-1} \leq a + b \leq 2^{n-1} - 1\)

  • 如果 \(a + b \geq 0\)\[ S = a + b = B(a + b) \]

  • 如果 \(a + b < 0\)\[ S = 2^n + (a + b) = B(a + b) \]

溢出。正溢出(\(a + b > 2^{n-1} - 1\))或负溢出(\(a + b < -2^{n-1}\)),同前述。

情况 4:\(a < 0, b \geq 0\)(负数 + 正数)

对称于情况 3: \[ B(a) = 2^n + a, \quad B(b) = b \]

\[ S = (2^n + a + b) \mod 2^n = (a + b) \mod 2^n \]

同上,验证无溢出和溢出情况。

根据补码公式的设计,可以得出硬件上“取反加一”的操作。