GESP 三级 第 02 讲:数据编码——原码、反码、补码

本讲定位:三级最抽象的一讲,也是最容易被学生”背下来但不理解”的一讲。官方大纲三级知识块 1 只有六个字:「原码、反码、补码」,但它是客观题的常驻考点,且只要考就一定考细节(负数的补码、0 的表示、取值范围为什么不对称)。本讲的目标不是让学生会背三个定义,而是回答一个问题:计算机没有减法器,负数是怎么存进去、又怎么算对的?

对应官方大纲:三级知识块 1「数据编码」——原码、反码、补码。

前置知识:三级第 01 讲(进制转换——本讲每一步都在二进制上做,$2^n$ 那张表必须已经背熟)、一级第 04 讲(基本数据类型与取值范围)。

代码说明:本讲所有代码均已用 g++ 11.5(-std=c++11)编译运行验证,输出结果即为文中标注结果。


1. 先看三道真题

第一道(单选):

用 8 位二进制表示,十进制数 $-5$ 的补码是( ) A. 10000101 B. 11111010 C. 11111011 D. 00000101

第二道(单选):

用 8 位二进制补码表示整数,可表示的范围是( ) A. $-127 \sim 127$ B. $-128 \sim 127$ C. $-128 \sim 128$ D. $0 \sim 255$

第三道(判断):

在补码表示中,数 0 有两种不同的编码。( )

答案:第一道选 C,第二道选 B,第三道错误。

这三道题就是本讲的三个必得分点:三种码的算法、范围的不对称、0 的唯一性。


2. 问题从哪来:负数怎么存

计算机里一个 int 就是固定的 32 个二进制位,一个 char 就是固定的 8 位。位里只能填 0 或 1,没有地方写负号。

所以必须约定一套规则:用这些 0/1 的组合去代表负数。 这套规则就叫编码。

2.1 两个必须先分清的词

术语 含义 例子(8 位)
真值 这个数在数学上的实际值,带正负号 $-5$
机器数 存在计算机里的那串 0/1 11111011

编码 = 从真值算出机器数;解码 = 从机器数读回真值。 原码、反码、补码就是三套不同的编码方案。

2.2 符号位