🎁 当前为 免费试看 内容 · 开通VIP 解锁 GESP 通关手册全部 1–8 级知识点 + 题库 + 详细解析
🌐 主站
📖 已学 0

📌 数据编码(原码 / 反码 / 补码)

所属等级:GESP 3级 | 难度:★★★ | 关键词:机器数、真值、原码、反码、补码、有符号、无符号

📝 考纲要求

  • 理解机器数与真值的概念:机器数是计算机里真正存储的 0/1 串,真值是它代表的实际数值(带正负);
  • 掌握原码 / 反码 / 补码三种编码的表示方法;
  • 掌握负数的补码 = 反码 + 1 的变换规则;
  • 理解为什么用补码:让加减法用同一套电路(统一成加法)、并让数字 0 只有一种表示;
  • 掌握有符号与无符号整数的表示范围,特别是 8 位补码范围为 -128 ~ 127。

📖 通俗讲解

💡 一句话理解 计算机只认 0 和 1,但现实中有正数也有负数。为了把“负号”也装进二进制,人们约定最左边一位当作符号位(0 表示正、1 表示负),于是同一个数字就有了原码、反码、补码三种“写法”。正数三码相同,负数需要变换。

以 8 位(一个字节)为例来对照:最左边的第 1 位是符号位,后面 7 位是数值位。

  • 原码:符号位 0/1 + 数值的二进制。最直白,但加减法麻烦,且 0 有 +0(00000000) 和 -0(10000000) 两种。
  • 反码:正数不变;负数的符号位不变、数值位按位取反(0 变 1,1 变 0)。
  • 补码:正数的补码 = 原码;负数的补码 = 它的反码 + 1。计算机真正存储和运算用的就是补码。

下面用一张对照表看清 +5、-5、-1 在 8 位下的三种编码(注意 -1 的补码是全 1,也就是 11111111,当作无符号数看就是 255):

ASCII 图解
        ┌───────────┬────────────┬────────────┬────────────┐
        │   数值     │   原码      │   反码      │   补码      │
        ├───────────┼────────────┼────────────┼────────────┤
        │   +5       │ 0000 0101  │ 0000 0101  │ 0000 0101  │  正数三码相同
        │   -5       │ 1000 0101  │ 1111 1010  │ 1111 1011  │  反码+1=补码
        │   -1       │ 1000 0001  │ 1111 1110  │ 1111 1111  │  ★补码全1=255
        └───────────┴────────────┴────────────┴────────────┘
        符号位:0 正 / 1 负
        正数:原码=反码=补码
        负数:原码= 1 + 数值位
              反码= 符号位不变,数值位取反
              补码= 反码 + 1

        -5 是怎么得到的?
          ① 原码:1 0000101   (符号位1,数值5=0000101)
          ② 反码:1 1111010   (数值位 0000101 取反 → 1111010)
          ③ 补码:1 1111011   (反码 +1 → 1111010 + 1 = 1111011)

        -1 是怎么得到的?
          ① 原码:1 0000001
          ② 反码:1 1111110   (0000001 取反 → 1111110)
          ③ 补码:1 1111111   (反码 +1 → 1111110 + 1 = 1111111 = 全1)

下面用 C++ 把 -1 的 8 位补码真正打印出来,验证它确实是 11111111:

🖼️ 图解

        8-bit: 最左 1 位是符号位(0 正 / 1 负)
        +5   原码 0 0000101 = 反码 0 0000101 = 补码 0 0000101
        -5   原码 1 0000101
             反码 1 1111010   (符号位不变,数值位取反)
             补码 1 1111011   (反码 + 1 = 补码)

        +-------+-----------+-----------+-----------+
        |  num  |  原码      |  反码      |  补码      |
        +-------+-----------+-----------+-----------+
        |  +5   | 0000 0101 | 0000 0101 | 0000 0101 |
        |  -5   | 1000 0101 | 1111 1010 | 1111 1011 |
        +-------+-----------+-----------+-----------+
        正数三码相同;负数:补码 = 反码 + 1
C++
#include <iostream>
using namespace std;
int main() {
    signed char a = -1;                 // 有符号字符,存的是 -1 的 8 位补码
    unsigned char b = (unsigned char)a; // 把那 8 位当作“无符号”来看
    cout << "有符号 -1 的 8 位补码:";
    for (int i = 7; i >= 0; i--)         // 从最高位到第 0 位依次输出
        cout << ((b >> i) & 1);
    cout << endl;
    cout << "它当作无符号数时的值 = " << (int)b << endl;  // 255
    return 0;
}
输出有符号 -1 的 8 位补码:11111111 它当作无符号数时的值 = 255

🔵 核心必背重点

✅ 必背
  • 正数三码相同:原码 = 反码 = 补码,符号位都是 0;
  • 负数三步走:原码(符号位 1 + 数值位)→ 反码(符号位不变、数值位取反)→ 补码(反码 + 1);
  • 8 位补码范围:-128 ~ 127(共 256 个数);其中 -128 的补码是 10000000,-1 的补码是 11111111;
  • 计算机用补码做加减法:减法变成“加一个负数”,一套加法电路搞定;
  • 0 只有一种表示:补码里 00000000 就是 0,没有 -0。
🔑
记忆口诀:“正数三码一模一样;负数反码取反再 +1 得补码;补码全 1 是 -1,范围 -128 到 127;加加减减都用补码,正零负零合一 0。”

🔴 考试拉分难点

⚠️ 难点
  • 为什么补码能统一加减法? 因为 a - b 等价于 a + (-b),而 -b 用补码表示后,直接做二进制加法、丢掉最高位的进位,结果正好正确(见例题 2)。
  • 为什么 0 只有一种表示? 在原码里 +0(00000000) 和 -0(10000000) 不同;而在补码里,-0 的反码是 11111111,加 1 后变成 100000000,超出 8 位被截断,结果也是 00000000,多出来的那个编码 10000000 就被用来表示 -128。
  • 有符号 vs 无符号范围:同样 8 位,unsigned char 范围是 0 ~ 255,signed char 范围是 -128 ~ 127;同样是 256 个数,只是“切分”方式不同。

🟡 高频易错陷阱

🚫 扣分坑点
  • 把原码当补码来加:用原码直接加 +5(00000101) + (-5)(10000101) 会得到错误结果;必须先转成补码再相加。
  • 忘记“反码 + 1”:负数补码不是只取反,取反后还要 +1,少一步就会算错(例如把 -1 写成 11111110 就错了,正确是 11111111)。
  • 混淆有符号/无符号:(unsigned char)-1 打印出来是 255,不是 -1;面试和考试常考这个“绕回”。
  • 写错范围:8 位有符号补码是 -128 ~ 127,不是 -127 ~ 127,最小值是 -128 不是 -127。

🧪 例题演练

例题 1(基础题):求 -1 的 8 位补码

题目:写出十进制数 -1 在 8 位补码下的二进制表示,并验证它当作无符号数时等于 255。

解答:按“负数三步走”: ① 原码 10000001; ② 反码(数值位取反)11111110; ③ 补码(反码 + 1)11111111。 所以 -1 的 8 位补码是 11111111,全 1;把它解释为无符号数就是 255。代码与上面基础讲解一致,输出为 11111111 和 255。

🚫 易错 常见错误答案是 10000001(那是原码)或 11111110(只取反没 +1)。记住:补码 = 反码 + 1,-1 的补码是全 1。

例题 2(模拟真题):用补码计算 5 + (-3)

题目:用 8 位补码计算 5 + (-3),写出二进制加法过程,结果应为 2。

解答:先写出两个数的 8 位补码:

ASCII 图解 · 补码加法
  +5 的补码:  0 0000101   →   0000 0101
  -3 的原码:  1 0000011
  -3 的反码:  1 1111100   (数值位 0000011 取反)
  -3 的补码:  1 1111101   (反码 +1)

  二进制竖式(补码相加):
       0000 0101   (+5)
     + 1111 1101   (-3 的补码)
     ───────────
    1 0000 0010   ← 最高位进位 1 被丢弃
       0000 0010   = 2  ✓

  结论:5 + (-3) 用补码相加,丢掉进位后正好是 0000 0010 = 2。
C++
#include <iostream>
using namespace std;
int main() {
    signed char a = 5;    // 补码 0000 0101
    signed char b = -3;   // 补码 1111 1101
    signed char c = a + b;
    cout << "5 + (-3) = " << (int)c << endl;  // 结果 2
    return 0;
}
输出5 + (-3) = 2

🛡️ 避坑总结

  1. 正负数分开记:正数原/反/补三码相同;负数先写原码,再取反得反码,最后 +1 得补码;
  2. 补码 = 反码 + 1,这是负数变换的核心公式,少一步就错;
  3. -1 的补码是全 1(11111111),当作无符号数就是 255,这是高频考点;
  4. 8 位有符号补码范围 -128 ~ 127,最小值是 -128(补码 10000000),不是 -127;
  5. 计算机用补码做加减法,减法变加法,统一电路、0 只有一种表示;
  6. 区分有符号/无符号:同样 8 位,无符号是 0~255,有符号是 -128~127,负数强转无符号会发生“绕回”。

💡 提示:按 ← → 方向键可在上一 / 下一知识点间快速翻页

GESP 3级 · 学习进度 0/0

📑 本页目录