编码

编码不是把数字换一种写法,而是把一个值压进固定宽度的机器状态里。看起来像数学,实际更像协议:哪些状态表示正负,哪些状态被浪费,哪些状态能直接交给加法器。

各编码方案对比

先把几个方案并排看。这个表不是为了背概念,而是为了看出它们的取舍:有的保留直觉,有的保留电路便利,有的服务浮点指数。

编码零的个数加法是否直接现在用在哪
原码 Sign-Magnitude2否IEEE 754 符号位
反码 One’s Complement2需要回卷进位几乎废弃
补码 Two’s Complement1是CPU 整数运算
移码 Biased Notation1不用于加法IEEE 754 指数字段

Sign-Magnitude 原码

原码最直观:最高位是符号位,剩下的位是绝对值。它像人在纸上写数,先写正负,再写大小。

+43 = 0_0101011
-43 = 1_0101011

它有两个零。加法也不能直接做,遇到不同符号时需要比较大小,再决定减法方向。

One’s Complement 反码

反码试图让负数进入位运算系统:正数不变,负数把正数的每一位取反。它比原码更接近机器,但还没有完全解决零的问题。

+43 = 00101011
-43 = 11010100

反码加法需要把最高位溢出的进位再加回最低位,这叫 end-around carry。这个规则并不优雅,说明它还没有和二进制加法器完全对齐。

Two’s Complement 补码

补码是现代 CPU 整数的主流,因为它把减法变成了加法。负数等于反码再加一,于是所有整数可以放在一个环里。

+43 = 00101011
-43 = 11010101

它只有一个零。代价是范围不对称:8 位补码可以表示 -128 到 +127。这个不对称不是错误,而是把一个原本浪费给 -0 的状态拿回来用了。

8-bit ring, signed values wrap through the same adder.

Biased Notation 移码

移码不是为加减法准备的,而是为了比较和排序。它给真实指数加上一个固定偏移,让负指数也能以无符号整数的形式保存。

以 IEEE 754 单精度为例,指数有 8 位,偏移量是 127。真实指数 e 会被存成 e + 127。

IEEE 754 Single Precision

单精度浮点数一共 32 位:1 位符号、8 位指数、23 位尾数。它不是在表示所有小数,而是在固定宽度里保存“数量级 + 有效数字”。

失去的状态去了哪里

每种编码都在用一种方式交换直觉、范围和电路便利。设计一个表示系统时,真正重要的不是把所有状态都填满,而是决定哪些状态值得被保留下来。

结尾

补码最后留下来的不是一个漂亮的数学对象,而是一套可以稳定工作的约定。机器喜欢约定,因为约定能够让下一步变得便宜。