原码 反码 补码的原理
CPU中以二进制来表示和计算数据,为了进行算数运算,先后出现了以下三种编码:原码,反码和补码。
名称 | 英文 | 用途 |
---|---|---|
原码 | Sign-Magnitude | 最直观的人类写法 |
反码 | Ones’ Complement | 过渡形式,历史上用过 |
补码 | Two’s Complement | 现代计算机通用 |
原码
最高位表示符号:0=正,1=负
剩下的位表示数值大小
优点:直观
缺点:有“+0”和“-0”两个表示方式,需要专门的减法电路
这里的+0和-0没有数学上的意义,单纯是表示上的差别
00000000
表示 +0
,10000000
表示-0
有时候做两数相等比较的时候会比较麻烦
如果要实现 A-B,则必须:
- 检查符号位
- 做加法或减法
- 根据符号位调整结果
例如对于8位二进制数:
十进制 | 原码二进制 |
---|---|
+5 | 00000101 |
-5 | 10000101 |
例1: -1 + -1 (原码)
步骤:
- +1(原码):
0000 0001
- -1(原码):
1000 0001
两数相加(原码):
1 | 1000 0001 |
结果变成 0000 0010
(把符号位当普通位加了) → 实际是 +2,不正确。
💡 在原码下,-1 + -1 得不到 -2,必须用单独的减法指令或额外处理逻辑才行。
例2:2+(-3) (原码)
步骤
- +2(原码):
0000 0010
- -3(原码):
1000 0011
相加:
1 | 0000 0010 |
这被解释为 -5(原码),但正确答案应是 −1-1−1。
💡 在原码下做正数 + 负数很难直接得到正确结果,需要硬件做“减法”并判断符号。
反码
正数:和原码一样
负数:在原码基础上符号位不变,数值位按位取反
缺点:仍然有“+0”和“-0”两种表示和“末位进位回加”问题(end-around carry)。
如果要实现A-B时可以这样做:
A+(B的反码)
在 反码加法中:
- 当两个符号位相加后,产生了一个“多出来的”进位到最高位以外。
- 具体来说:当两个数同号,或一个数是负数另一个是正数,但反码相加时结果大于最大可表示的正值,会产生环绕进位。
📌 重点记忆:
只要反码相加结果溢出了最高位,且你要得到正确值,就要把溢出的1加回最低位。
例1:8 位反码:
- +2 (反码) =
0000 0010
- +3 (反码) =
0000 0011
相加:
1 | 0000 0010 |
例2:典型的回加例子(-1 + -1)
- -1 原码 =
1000 0001
→ 反码 =1111 1110
再加 -1:
1 | 1111 1110 |
去掉溢出的1(符号之外)再加回最低位:
1 | 1111 1100 + 1 = 1111 1101 |
这是 -2 的反码。正确。
补码
现代计算机都用补码。
- 正数:与原码、反码相同
- 负数:反码+1
- 好处:
- 加减法可以用同一个加法器完成
- 只有一个零
- 范围可以多出一个负数(-128~+127 for 8-bit)
例如:
十进制 | 原码 | 反码 | 补码 |
---|---|---|---|
+5 | 00000101 | 00000101 | 00000101 |
-5 | 10000101 | 11111010(反码) | 11111011(补码) |
对于 n 位二进制: |
- 负数的补码 = $a^{n} - |X|$
- 负数的补码再取补码(再求反码+1)就回到正数
如果要实现A-B时可以这样做:
A+(B的补码)
只要有一个加法器,就能同时完成加法和减法,因为:
- B 为正:直接加
- B 为负:加上它的补码
补码天然让溢出和进位处理一致。
📌 优点:无需单独的减法器/减法指令,只需:
- 把第二个操作数取补码(硬件中通过反码+1实现)
- 然后用同一个加法器执行加法
例 1:−1+−1(补码)
步骤
- -1(补码)**:
- 原码:
1000 0001
- 反码:
1111 1110
- 补码:
1111 1111
- 原码:
两数相加:
1 | 1111 1111 |
丢弃最高位的进位(溢出位):
1111 1110
→ 这是 -2 的补码(因为负数补码 = 反码 + 1 → 反码 = 1111 1101
→ 原码 = 1000 0010
)。
✅ 直接得出 -2。
📌 补码不需要回加。
例 2:2+(−3)(补码)
步骤
- +2(补码):
0000 0010
- -3(补码):
- 原码:
1000 0011
- 反码:
1111 1100
- 补码:
1111 1101
- 原码:
两数相加:
1 | 0000 0010 |
1111 1111
→ 这是 -1 的补码。
✅ 结果正确:2+(−3)=−1。