GESP C++ 3 级 · 知识点

数据编码(原码、反码、补码)

GESP C++ 三级要求理解原码、反码、补码的表示方法,能完成三者之间的转换,并说清计算机为什么用补码存储整数。这一节既要会算,也要理解补码把减法变成加法的意义。

对应知识域:数据编码(原码、反码、补码)相关真题 4 套

本页为本站原创整理,例题与解析均由本站编写,不取自任何题库原题;考试范围以 CCF 官方公布为准,本平台不是 GESP 官方平台。

考纲要求

  • 理解原码由符号位和数值位组成,最高位为 0 表示正数、为 1 表示负数。
  • 掌握负数反码与补码的求法:反码是符号位不变、数值位取反,补码是反码再加 1。
  • 知道正数的原码、反码、补码三者相同。
  • 理解补码能把减法转成加法,使计算机用同一套加法电路完成加减运算。

典型题型

  • 给出一个十进制负数,要求写出它在 8 位下的原码、反码和补码。
  • 给出补码,要求还原成十进制数。
  • 判断若干说法,例如「补码 10000000 表示 -0」。

常见错误

  • 求负数的反码时把符号位也取反,导致结果错误。反码只把数值位取反,符号位保持为 1。
  • 补码求法记成「数值位取反后不加 1」,忘了末尾加一。
  • 把 8 位补码的范围记成 -128 到 128。实际是 -128 到 127,正数没有 128。
  • 以为补码 10000000 表示 -0。补码中 0 只有一种表示,10000000 表示 -128。

深入理解

三种编码只差一步

以 8 位为例,编码一个整数分三步:

  • 原码:最高位当符号位(0 表示正,1 表示负),其余位写绝对值的二进制。所以 -5 的原码是 10000101。
  • 反码:正数的反码与原码相同;负数的反码是符号位不动,其余各位取反。-5 的反码是 11111010。
  • 补码:反码加 1。-5 的补码是 11111011。

记忆口诀是「正数三码相同,负数原码 → 取反 → 加一」。反过来由补码求原码,同样走「减一 → 取反」,因为这两步互为逆运算。题目常给一个补码让你求十进制值,稳妥做法是先判断符号位:最高位是 0 直接按位权算,最高位是 1 就减一取反得到原码,再读出绝对值加负号。

为什么非要用补码

用原码表示时有两个麻烦:一是 0 有两种写法(00000000 和 10000000),判断「是不是 0」要写两次;二是减法要单独设计一套电路。

补码同时解决这两个问题。0 只有一种表示,而且减法可以改写成加法:a - b 等价于 a + (-b),CPU 只需要一个加法器就能同时完成加减。「把减法变成加法,让 0 表示唯一」是补码存在的全部理由,简答题只要答到这两点就够了。

8 位能表示的范围不对称

8 位补码的范围是 -128 到 127,负数比正数多一个。原因是 10000000 这个码不再表示「负零」,而被规定为 -128。理解这一点,遇到「8 位补码能表示多少个数」时答案就是 256 个,遇到「超出范围会怎样」时答案是溢出回绕:127 加 1 变成 -128,这是位运算题里常见的坑。

n 位补码的范围可以记成 -2^(n-1) 到 2^(n-1) - 1。16 位是 -32768 到 32767,32 位是 -2147483648 到 2147483647,这两个数在竞赛题里出现频率很高。

自编例题

求 -5 的 8 位原码、反码与补码

用 8 位二进制写出十进制 -5 的原码、反码和补码。

// 8 位补码 11111011 按有符号数解释
char c = (char)0xFB;    // 0xFB = 251
cout << (int)c << endl; // 输出 -5

-5 的绝对值是 5,8 位二进制写作 0000 0101。符号位置 1 得到原码 1000 0101。反码保留符号位,其余位取反,得到 1111 1010。补码在反码末位加 1,得到 1111 1011,也就是十六进制的 0xFB。把它按有符号 char 解释时,最高位为 1 代表负数,结果为 -5;若按无符号数解释则是 251。同一串二进制,类型不同解释就不同。

相关真题

这块内容在整条路线里的位置:GESP C++ 3 级备考路径。

READY TO START

开始练习

先做一套本级别测评,报告会指出哪些知识点需要重点补;再回到本页对照考纲要求逐条核对,把不确定的条目记下来集中练。

常见问题

为什么计算机用补码表示整数?

补码让加法和减法共用同一套电路,0 也只有一种表示,简化了硬件设计,同时扩大了可表示的负数范围。

8 位补码能表示的范围是多少?

范围是 -128 到 127。最高位为符号位,剩下 7 位表示数值,负数比正数多一个。

原码里有 +0 和 -0 吗?

原码中 00000000 和 10000000 分别表示 +0 和 -0,出现两个零;补码中零只有 00000000 一种表示。

本级别其他知识点

官方依据