数制转换 · 补码原理

补码快速转换与 2ⁿ 减法原理

补码的快速心算技巧,以及 模 − 补码 = 绝对值 的数学本质

01  /  补码二进制 → 十进制

补码的快速转换

先看最高位:如果是 0,就是正数,直接按权值相加。如果是 1,是负数,用以下方法:

通用 · 不会出错

方法一:取反加 1

1010 1111 为例,最高位是 1,说明是负数:

原数: 1010 1111 按位取反: 0101 0000 加 1: 0101 0001 = 81 结果 = −81

为什么取反加 1 能得到绝对值?

这个操作本质上就是在算 模 − 补码

模 − 补码 = |X|
8 位的模 = 2⁸ = 256
对负数 X,补码定义为 2ⁿ − |X|
所以 2ⁿ − 补码 = |X|

而"取反加 1"正好等价于"模 − 补码"。推导如下:

恒等式: 补码 + ~补码 = 1111 1111 = 2ⁿ − 1 = 255 所以: ~补码 = 255 − 补码 取反加1: ~补码 + 1 = (255 − 补码) + 1 = 256 − 补码 = 2ⁿ − 补码 = |X|
结论:取反加 1 并不是一个"碰巧有效的技巧",它的数学本质就是 模 − 补码 = 绝对值。取反得到 2ⁿ−1−补码,再加 1 补上差的那个 1,刚好等于 2ⁿ−补码。

用 −81 验证:

补码: 1010 1111 = 175 取反: 0101 0000 = 255 − 175 = 80 加 1: 0101 0001 = 80 + 1 = 81 等价于: 256 − 175 = 81 = |−81| ✔
负数 补码(十进制) 补码(二进制) 取反 加 1 = 256 − 补码 验证
−1 255 1111 1111 0000 0000 = 0 1 256 − 255 = 1
−50 206 1100 1110 0011 0001 = 49 50 256 − 206 = 50
−81 175 1010 1111 0101 0000 = 80 81 256 − 175 = 81
−127 129 1000 0001 0111 1110 = 126 127 256 − 129 = 127
−128 128 1000 0000 0111 1111 = 127 128 256 − 128 = 128

★ 最快 · 考试推荐

方法二:−128 + 剩余位

8 位补码中,最高位的权值是 −128(不是 +128):

1010 1111 最高位 = 1 → −128 剩余 7 位 = 010 1111 = 32+8+4+2+1 = 47 −128 + 47 = −81
优势:不需要取反,直接算,一步到位。只需记住最高位权值是 −128(16 位是 −32768)。
02  /  补码的数学本质

为什么 2⁸ − 负数的补码 = 对应正数

从补码的定义推导

补码 = 2ⁿ − |X|
这就是补码的定义:
负数 X 的补码等于模(2ⁿ)减去它的绝对值。

把定义倒过来:

定义: 补码 = 2ⁿ − |X| 反推: 2ⁿ − 补码 = 2ⁿ − (2ⁿ − |X|) = 2ⁿ − 2ⁿ + |X| = |X|
结论:这不是巧合,这就是定义本身的逆运算。模 − 补码 = |X| 是补码编码方式的直接结果。

为什么补码要这样定义

补码的设计目的是让减法变成加法。想让 A + (−B) 在硬件上直接用加法器完成:

A + [−B 的补码] = A + (2⁸ − B) = A − B + 256 256 = 2⁸,对 8 位寄存器来说 从最高位溢出丢掉 寄存器里剩下:A − B ← 正确的减法结果
本质:补码的定义 2ⁿ − |X| 不是随意选择,而是为了让加法器同时完成加法和减法。模 − 补码 = |X| 是这套编码体系的自然推论,取反加 1 则是这个减法在二进制层面的具体操作方式。三者是同一件事的不同表述。