外观
整数与补码表示
约 801 字大约 3 分钟
2025-12-26
进制解决不了正负的问题
在前面的文章中, 我们讨论了进制/进制转换/以及小数的表示问题.
但有一个问题一直被刻意回避:
负数是如何被表示的?
进制只能回答数值如何展开, 却无法回答正负如何区分.
因此, 负数的表示并不是进制的问题, 而是编码方式的问题.
为什么计算机必须使用定长整数
计算机中的整数, 并不是无限长的.
在实际系统中, 整数通常具有固定长度, 例如:
- 8 位
- 16 位
- 32 位
- 64 位
这意味着:
- 每一个整数, 都只能使用有限的二进制位.
- 最高位, 必须承担某种符号含义.
最直觉的方案: 符号位 + 绝对值
最容易想到的负数表示方式是:
- 最高位表示符号(0 为正, 1 为负).
- 其余位表示数值的绝对值.
例如(8 位):
+5−5=00000101=10000101
这种方式直观, 但存在严重问题:
- 加减法需要额外处理符号位.
- 会出现 +0 和 -0 两种表示.
因此, 它并不适合用于通用计算.
反码: 向前迈了一步, 但还不够
在符号位方案的基础上, 引入了反码的概念.
规则是:
- 正数: 与原码相同.
- 负数: 对除符号位外的所有位取反.
例如(8 位):
+5−5=00000101=11111010
反码解决了部分运算问题, 但仍然存在:
- +0 和 -0 依然共存.
- 加法电路仍然复杂.
补码: 工程上的最终选择
为了解决上述所有问题, 计算机最终选择了补码(Two's Complement).
补码的定义
对于一个 N 位整数:
- 正数的补码 = 原码.
- 负数的补码 = 反码 + 1.
等价表述为:
负数的补码 = 2n − 该数的绝对值
补码的示例
以 8 位整数为例, 表示 -5:
+5 的二进制:
00000101
取反:
11111010
加 1:
11111011
因此:
−5=11111011
为什么补码如此重要
补码的核心优势在于:
- 加减法可以统一处理.
- 不需要区分正负数.
- 不存在 +0 和 -0 的歧义.
例如, 在补码系统中:
(+5)+(−5)=0
可以直接用二进制加法完成, 而无需特殊逻辑.
在补码体系下, 减法被消灭了, 只剩加法.
如何从补码还原十进制
判断一个补码表示的整数, 需要先看最高位:
- 最高位为 0: 正数, 直接按位权展开.
- 最高位为 1: 负数, 执行以下步骤:
- 对所有位取反.
- 加 1.
- 按正数方式计算结果.
- 添加负号.
示例
11101011
取反:
00010100
加 1:
00010101
计算十进制:
21
结果为:
−21
补码的取值范围
对于 N 位补码整数:
- 最小值: −2n−1
- 最大值: 2n−1
例如:
- 8 位整数范围: −128 127
- 32 位整数范围: −231 231−1
版权所有
版权归属:洱海