本讲定位:三级最抽象的一讲,也是最容易被学生”背下来但不理解”的一讲。官方大纲三级知识块 1 只有六个字:「原码、反码、补码」,但它是客观题的常驻考点,且只要考就一定考细节(负数的补码、0 的表示、取值范围为什么不对称)。本讲的目标不是让学生会背三个定义,而是回答一个问题:计算机没有减法器,负数是怎么存进去、又怎么算对的?
对应官方大纲:三级知识块 1「数据编码」——原码、反码、补码。
前置知识:三级第 01 讲(进制转换——本讲每一步都在二进制上做,$2^n$ 那张表必须已经背熟)、一级第 04 讲(基本数据类型与取值范围)。
代码说明:本讲所有代码均已用 g++ 11.5(
-std=c++11)编译运行验证,输出结果即为文中标注结果。
第一道(单选):
用 8 位二进制表示,十进制数 $-5$ 的补码是( ) A.
10000101B.11111010C.11111011D.00000101
第二道(单选):
用 8 位二进制补码表示整数,可表示的范围是( ) A. $-127 \sim 127$ B. $-128 \sim 127$ C. $-128 \sim 128$ D. $0 \sim 255$
第三道(判断):
在补码表示中,数 0 有两种不同的编码。( )
答案:第一道选 C,第二道选 B,第三道错误。
- $-5$ 的原码
10000101(选项 A)、反码11111010(选项 B)、补码11111011(选项 C)。四个选项把三种码和绝对值全放进去了——这就是这类题的标准出法,不分清三种码必错。- 补码的范围左边多一个:$-128 \sim 127$。
- 原码和反码的 0 有两种编码($+0$ 和 $-0$),补码的 0 只有一种——这正是补码能多表示一个负数的原因。
这三道题就是本讲的三个必得分点:三种码的算法、范围的不对称、0 的唯一性。
计算机里一个 int 就是固定的 32 个二进制位,一个 char 就是固定的 8 位。位里只能填 0 或 1,没有地方写负号。
所以必须约定一套规则:用这些 0/1 的组合去代表负数。 这套规则就叫编码。
| 术语 | 含义 | 例子(8 位) |
|---|---|---|
| 真值 | 这个数在数学上的实际值,带正负号 | $-5$ |
| 机器数 | 存在计算机里的那串 0/1 | 11111011 |
编码 = 从真值算出机器数;解码 = 从机器数读回真值。 原码、反码、补码就是三套不同的编码方案。