1. 原码(Sign-Magnitude)
- 定义:最高位表示符号(0正,1负),其余位为数值的绝对值。
- 示例(8位):
- +5:
0000 0101
- -5:
1000 0101
- +5:
- 优点:直观,与人类书写习惯一致。
- 缺点:
- 加减运算复杂:需判断符号位,逻辑电路设计复杂。
- 零的歧义:存在
+0 (0000 0000)
和-0 (1000 0000)
两种表示。
- 应用场景:早期计算机(如IBM 704),现代计算机已弃用。
2. 反码(1’s Complement)
- 定义:正数与原码相同;负数为原码符号位不变,其余位按位取反。
- 示例(8位):
- +5:
0000 0101
- -5:
1111 1010
(原码1000 0101
取反)
- +5:
- 优点:减法可转换为加法(需处理循环进位)。
- 缺点:
- 零的歧义:仍然存在
+0 (0000 0000)
和-0 (1111 1111)
。 - 运算复杂:需处理进位循环,硬件实现复杂。
- 零的歧义:仍然存在
- 应用场景:早期通信协议校验(如TCP校验和)。
3. 补码(2’s Complement)
- 定义:正数与原码相同;负数为其绝对值的原码取反后加1。
- 示例(8位):
- +5:
0000 0101
- -5:
1111 1011
(绝对值原码0000 0101
→ 取反1111 1010
→ 加1 →1111 1011
)
- +5:
- 优点:
- 统一加减法:减法转换为加法,无需额外电路。
- 零唯一:
0
仅一种表示(0000 0000
)。 - 扩展性强:直接支持有符号数运算。
- 缺点:负数转换需额外加1操作。
- 应用场景:现代计算机标准表示法。
4. 关键对比
特性 | 原码 | 反码 | 补码 |
---|---|---|---|
零的表示 | +0 和-0 两种 |
+0 和-0 两种 |
0 唯一(000...0 ) |
加减运算 | 需判断符号,逻辑复杂 | 需处理循环进位 | 直接相加,无需额外逻辑 |
数值范围 | -127 ~ +127(8位) | -127 ~ +127(8位) | -128 ~ +127(8位) |
硬件实现 | 复杂(需符号判断) | 较复杂(循环进位) | 简单(统一加法器) |
5. 补码运算原理
加法规则:直接按二进制相加,忽略最高位进位。
- 示例:5 + (-3) = 2
- 5的补码:
0000 0101
- -3的补码:
1111 1101
- 相加:
0000 0101 + 1111 1101 = 1 0000 0010
→ 舍去进位 →0000 0010
(即+2)
- 5的补码:
- 示例:5 + (-3) = 2
溢出检测:若两个正数相加结果为负,或两个负数相加结果为正,则溢出。
- 示例:127 + 1 = -128(8位补码)
- 127:
0111 1111
- 1:
0000 0001
- 结果:
1000 0000
(-128,溢出)
- 127:
- 示例:127 + 1 = -128(8位补码)
6. 补码扩展与截断
- 符号扩展:正数补0,负数补1。
- 例:8位补码
1111 1011
(-5)→ 16位补码1111 1111 1111 1011
。
- 例:8位补码
- 截断风险:高位截断可能改变数值符号(需确保数值在目标位数范围内)。
7. 总结
- 补码统治原因:运算统一、零唯一、硬件简单。
- 原码/反码淘汰:运算复杂、零歧义。
- 实践技巧:
- 负数转补码:取反加1。
- 快速计算补码:从右向左找到第一个1,其左侧全部取反。
- 例:
0010 0100
→ 补码为1101 1100
(右侧第一个1在第三位,左侧全部取反)。
- 例:
本文作者:
ICXNM-ZLin
本文链接: https://talent-tudou.github.io/2025/03/02/C语言/原码、反码、补码详解/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!
本文链接: https://talent-tudou.github.io/2025/03/02/C语言/原码、反码、补码详解/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!