补码是计算机中最常用的有符号整数表示方法。对于 n 位二进制数(含 1 位符号位):
补码的表示范围(n 位含符号位):最大正数 $2^{n-1} - 1$,最小负数 $-2^{n-1}$,共 $2^n$ 个数(+0 与 -0 统一为全 0)。
$$[x+y]_补 = [x]_补 + [y]_补 \pmod{2^n}$$
$$[x-y]_补 = [x]_补 + [-y]_补 \pmod{2^n}$$
减法转化为加法,关键是求 $[-y]_补$(变补/取补操作):将 $[y]_补$ 的所有位(包括符号位)取反,末位加 1。注意:变补是对整个补码(含符号位)操作,不同于原码求补码。
溢出发生在:两个同号数相加,结果的符号与操作数符号不同。
| 条件 | 溢出情况 |
|---|---|
| 正 + 正 = 负 | 正溢出(上溢) |
| 负 + 负 = 正 | 负溢出(下溢) |
| 正 + 负 | 不可能溢出 |
方法一 · 单符号位法:$V = A_s B_s \overline{S_s} + \overline{A_s}\, \overline{B_s} S_s$,其中 $A_s, B_s$ 为操作数符号位,$S_s$ 为结果符号位。
方法二 · 双符号位法(变形补码/模 4 补码):两位符号位 00 正、11 负。
| 双符号位结果 | 含义 |
|---|---|
| 00 | 正数,无溢出 |
| 01 | 正溢出(上溢) |
| 10 | 负溢出(下溢) |
| 11 | 负数,无溢出 |
溢出判断:$V = S_{s1} \oplus S_{s2}$(两个符号位不同即溢出)。
方法三 · 进位判断法:设符号位产生的进位为 $C_s$,最高数值位产生的进位为 $C_1$:
$$V = C_s \oplus C_1$$
| 概念 | 说明 |
|---|---|
| 原码 | 符号位 + 绝对值,正负数表示对称 |
| 反码 | 正数同原码;负数符号位不变,数值位取反 |
| 补码 | 正数同原码;负数 = 反码 + 1 |
| 移码 | 补码的符号位取反,用于浮点数阶码 |
| 变补 | 由 $[y]_补$ 求 $[-y]_补$,所有位取反加 1 |
| 模 | 补码运算溢出的自然丢弃值,n 位定点整数模为 $2^n$ |
| 溢出 | 运算结果超出了补码能表示的范围 |
| 上溢/正溢出 | 正数 + 正数结果为负,超出最大正数 |
| 下溢/负溢出 | 负数 + 负数结果为正,超出最小负数 |
0 0101101 + 0 0100101 ----------- 0 1010010 → 真值 +82 ✓(45+37=82,无溢出)
变补:$[y]_补 = 1\ 1011011$ → 取反 $0\ 0100100$ → 加 1 → $[-y]_补 = 0\ 0100101$(即 +37)。
0 0101101 + 0 0100101 ----------- 0 1010010 → +82 ✓(45-(-37)=82)
0 1100100 + 0 0110010 ----------- 1 0010110 → 符号位变 1!正+正=负 → 正溢出
进位法验证:$C_1 = 1$(数值位最高位有进位),$C_s = 0$(0+0+1=1 无进位),$V = 0 \oplus 1 = 1$ → 溢出 ✓(150 > 127)。
1 0011100 + 1 1001110 ----------- 10 1101010 → 舍弃最高进位 → 0 1101010 符号位变 0!负+负=正 → 负溢出
(-150 < -128)
00 1000001 + 00 1000110 ------------ 01 0000111 → 双符号位 01 → 正溢出 ✓(135 > 127)
| 操作 | 时间复杂度 | 硬件实现 |
|---|---|---|
| 补码加法 | O(n),n 为字长 | 并行加法器(行波进位/超前进位) |
| 补码减法 | O(n) | 加法器 + 变补电路(取反 + 1) |
| 变补操作 | O(n) | 取反器 + 加 1(可复用加法器) |
| 溢出判断 | O(1) | 仅需最高位进位比较,硬件开销极小 |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。