补码系统设计了一套机制,将数学上的有符号整数范围 [−2n−1,2n−1−1] 映射到无符号整数范围 [0,2n−1]。映射后,映射后,所有的算术运算(加法、减法等)在无符号二进制运算下,结果等价于有符号整数的数学运算。
补码的核心是设计一种“编码”,让负数、正数在二进制世界里用统一的规则运算,结果和数学一致。
在这种映射规则下,对于正数和零(x≥0),直接用二进制表示,最高位为 0,即B(x)=x,范围:[0,2n−1−1]。对于负数(x<0),负数 −x(其中 x>0)映射为:B(−x)=2n−x,范围:[−2n−1,−1],整个范围正好覆盖 [0,2n−1],共 2n 个值,无浪费。
对于任意有符号整数 k∈[−2n−1,2n−1−1]:
如果 k≥0:
如果 k<0:
B(k)=2n+k
因为 k=−x(x>0),所以:
B(−x)=2n−x=2n+(−x)
这一映射确保:
-
每个有符号整数 k 对应唯一的无符号值 B(k)∈[0,2n−1]。
-
反过来,每个无符号值 u∈[0,2n−1] 对应一个有符号整数。
补码的映射不仅覆盖了范围,还保证了运算(特别是加法、减法)在无符号二进制下的结果与有符号整数的数学运算一致。
对于有符号整数加法,有x+(−x)=0,在补码系统中,正数被设计为B(x)=x,负数被设计为B(−x)=2n−x,相加:
B(x)+B(−x)=x+(2n−x)=2n
在 n 位硬件中,2n=10000...0000(第 n+1 位为 1),寄存器只保留低 n 位:0000...0000=0。从模 2n 视角看:
2n≡0(mod2n)
所以:
x+(2n−x)≡0(mod2n)
对于任意任意 a,b∈[−2n−1,2n−1−1],计算 a+b,结果 s,补码映射:
B(a)+B(b)mod2n=B(s)
如果 s 在范围内,结果正确;如果溢出,模 2n 保证循环性。
对于减法,可以转为加法,a−b=a+(−b),B(−b)=2n−b。
硬件用加法器:
B(a)+B(−b)=a+(2n−b)
模 2n 后得到正确结果。
要保证循环性(溢出处理),补码形成模 2n 的圆环,最大正数:2n−1−1=0111...1111,加 1:
2n−1−1+1=2n−1=2n−2n−1=B(−2n−1)
最小负数:−2n−1=1000...0000,减 1:
2n−2n−1−1=2n−1−1
溢出时,数值在 [−2n−1,2n−1−1] 内循环,硬件无需额外处理。
推导 B(a)+B(b)mod2n 如何映射到 B(a+b):
对于任意 a:
B(a)={a2n+aif a≥0if a<0
同理,B(b) 类似。
计算 B(a)+B(b),结果模 2n:
S=(B(a)+B(b))mod2n
S 是 n 位寄存器的输出,范围 [0,2n−1]。
需要证明:
-
如果 a+b∈[−2n−1,2n−1−1](无溢出),则:S=B(a+b)
-
如果 a+b 溢出(超出范围),则 S 是模 2n 下的正确映射。
假设 a+b=s(数学和)。
情况 1:a≥0,b≥0(正数 + 正数)
补码:
B(a)=a,B(b)=b
硬件加法:
B(a)+B(b)=a+b
结果:
S=(a+b)mod2n
无溢出。如果 a+b≤2n−1−1(在范围内):S=a+b=B(a+b)
正溢出。如果 a+b>2n−1−1(超出正数范围):S=(a+b)mod2n。在补码中,这对应负数(圆环循环)。
情况 2:a<0,b<0(负数 + 负数)
补码:
B(a)=2n+a,B(b)=2n+b
硬件加法:
B(a)+B(b)=(2n+a)+(2n+b)=2n+1+(a+b)
结果:
S=(2n+1+(a+b))mod2n
因为 2n+1=2⋅2n≡0(mod2n)(因为 2nmod2n=0),所以,S=(a+b)mod2n。
无溢出。如果 −2n−1≤a+b<0:S=2n+(a+b)=B(a+b)
负溢出。如果 a+b<−2n−1:a+b 是负数,模 2n 后:S=2n+(a+b),可能映射到正数(圆环循环)。
情况 3:a≥0,b<0(正数 + 负数)
补码:
B(a)=a,B(b)=2n+b
硬件加法:
B(a)+B(b)=a+(2n+b)=2n+(a+b)
结果:
S=(2n+(a+b))mod2n=(a+b)mod2n
无溢出。如果 −2n−1≤a+b≤2n−1−1:
溢出。正溢出(a+b>2n−1−1)或负溢出(a+b<−2n−1),同前述。
情况 4:a<0,b≥0(负数 + 正数)
对称于情况 3:
B(a)=2n+a,B(b)=b
S=(2n+a+b)mod2n=(a+b)mod2n
同上,验证无溢出和溢出情况。
根据补码公式的设计,可以得出硬件上“取反加一”的操作。