01 / 补码二进制 → 十进制
补码的快速转换
先看最高位:如果是 0,就是正数,直接按权值相加。如果是 1,是负数,用以下方法:
通用 · 不会出错
方法一:取反加 1
以 1010 1111 为例,最高位是 1,说明是负数:
原数: 1010 1111
按位取反: 0101 0000
加 1: 0101 0001 = 81
结果 = −81
为什么取反加 1 能得到绝对值?
这个操作本质上就是在算 模 − 补码:
而"取反加 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|
反推: 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 则是这个减法在二进制层面的具体操作方式。三者是同一件事的不同表述。