原码、反码、补码¶
方法速览¶
| 任务 | 方法 | 口诀 |
|---|---|---|
| 正数求三码 | 原码 = 反码 = 补码(符号位 0) | 正数三码相同 |
| 负数求反码 | 符号位不变,数值位按位取反 | 符号不动,其余取反 |
| 负数求补码 | 反码末位加 1 | 反码加一 |
| 补码 → 原码 | 与正向同一套操作(取反加一 / 快捷法) | 来回通用 |
| n 位范围 | 补码 \([-2^{n-1},\ 2^{n-1}-1]\);无符号 \([0,\ 2^{n}-1]\) | 负多一个 |
三种编码规则¶
最高位是符号位:0 表示正数、1 表示负数;其余位是数值位。
以 8 位为例(\(53 = 32+16+4+1 = 0110101_2\)):
| 真值 | 原码 | 反码 | 补码 |
|---|---|---|---|
| \(+53\) | 00110101 |
00110101 |
00110101 |
| \(-53\) | 10110101 |
11001010 |
11001011 |
| \(+0\) | 00000000 |
00000000 |
00000000 |
| \(-0\) | 10000000 |
11111111 |
00000000 |
| \(-128\) | 无法表示 | 无法表示 | 10000000 |
看表得三条结论:
- 正数:三码完全相同,不需要任何变换;
- 负数:反码 = 原码数值位取反(符号位不动);补码 = 反码 + 1;
- \(-0\) 的补码加 1 后回到
00000000——补码里 0 唯一,省下的10000000正好拿去表示 \(-128\),所以负数比正数多一个。
互转方法与快捷法¶
正向:求 \(-53\) 的三码(分三步)
- 写绝对值的 8 位二进制,符号位改 1:\(53 = 0110101_2\) → 原码
10110101 - 符号位不变、数值位取反:
0101101 → 1010010→ 反码11001010 - 反码末位加 1:
11001010 + 1→ 补码11001011
逆向:补码 → 原码的快捷法
从右往左找到第一个 1:它自己和它右边的位不动,它左边除符号位外的位取反。
例:补码 11010100 求原码——从右数第 3 位是第一个 1:
| 符号位 | 左 4 位 | 右 3 位 | |
|---|---|---|---|
| 补码 | 1 |
1010 |
100 |
| 处理 | 不变 | 取反 → 0101 |
不变 |
| 原码 | 1 |
0101 |
100 |
原码 10101100 = \(-(32+8+4) = -44\)。
快捷法来回通用(原码→补码、补码→原码同一套),验证:\(-44\) 原码 10101100 → 数值位取反 1010011 → 加 1 1010100 → 补码 11010100,回到出发值。
补码的意义¶
减法变加法。 有了补码,CPU 只需要一套加法器:\(a - b\) 就按 \(a + (b\text{ 的补码})\) 计算。
例:8 位下算 \(5 - 3\)(\(-3\) 的补码 = 11111101):
反向 \(3 - 5\)(\(-5\) 的补码 = 11111011):
0 唯一。 原码、反码里 \(+0\) 和 \(-0\) 各占一个编码,判等还要特判;补码里 0 只有一种写法,多出的 10000000 表示 \(-128\)——这就是“负数比正数多一个”的来源。
范围与溢出¶
n 位补码的范围:
以 8 位清点:负数 \(-128 \sim -1\) 共 128 个,\(0\) 一个,正数 \(1 \sim 127\) 共 127 个,合计 \(256 = 2^8\),编码不重复不遗漏。
| 位数 | 补码(有符号)范围 | 无符号范围 |
|---|---|---|
| 8 | \(-128 \sim 127\) | \(0 \sim 255\) |
| 16 | \(-32768 \sim 32767\) | \(0 \sim 65535\) |
32(int) |
\(-2147483648 \sim 2147483647\) | \(0 \sim 4294967295\) |
超出范围就是溢出:8 位下 \(127 + 1\) 的补码结果是 10000000,反而变成 \(-128\)。
练习题目¶
练习 1 · 正数三码相同¶
题目
\(+45\) 的 8 位补码是( )
- A. \(10101101\)
- B. \(00101101\)
- C. \(11010010\)
- D. \(11010011\)
答案与解析
答案:B
正数三码相同:\(45 = 32+8+4+1 = 101101_2\) → 00101101。A/C/D 都是负数 \(-45\) 的三码——只有负数才需要取反加一。
练习 2 · 求负数的反码¶
题目
\(-45\) 的 8 位反码是( )
- A. \(11010010\)
- B. \(11010011\)
- C. \(10101101\)
- D. \(00101101\)
答案与解析
答案:A
先写原码:\(45 = 0101101_2\),符号位改 1 → 10101101;符号位不动、数值位取反 0101101 → 1010010 → 反码 11010010。B 是反码多加了 1(那是补码)。
练习 3 · 求负数的补码¶
题目
\(-45\) 的 8 位补码是( )
- A. \(11010010\)
- B. \(10101101\)
- C. \(11010011\)
- D. \(10101110\)
答案与解析
答案:C
原码 10101101 → 反码 11010010 → 加 1 → 补码 11010011。三步连做:原码 → 取反(数值位)→ 加一。
练习 4 · 补码求真值¶
题目
8 位补码 \(11101011\) 表示的十进制数是( )
- A. \(-21\)
- B. \(-11\)
- C. \(-20\)
- D. \(11\)
答案与解析
答案:A
快捷法:从右往左第 1 位就是 1,它不动,左边除符号位外取反(数值位 \(1101011 \to 0010100\))→ 原码 10010101 = \(-(16+4+1) = -21\)。
练习 5 · 快捷法(第一个 1 不在末位)¶
题目
8 位补码 \(11010100\) 的原码是( )
- A. \(10101011\)
- B. \(11010100\)
- C. \(10101101\)
- D. \(10101100\)
答案与解析
答案:D
从右往左第一个 1 在第 3 位:右边 100 不动,左边(符号位除外)1010 取反成 0101 → 原码 1 | 0101 | 100 = 10101100,真值 \(-44\)。
练习 6 · −1 的补码¶
题目
8 位补码表示的 \(-1\) 是( )
- A. \(10000001\)
- B. \(11111110\)
- C. \(11111111\)
- D. \(10000000\)
答案与解析
答案:C
原码 10000001 → 反码 11111110 → 加 1 → 11111111。全 1 就是 −1;A 是 −1 的原码,别混淆。
练习 7 · 0 的表示¶
题目
关于数 0 的表示,正确的是( )
- A. 原码中 0 只有一种表示
- B. 反码中 0 只有一种表示
- C. 补码中 0 有两种表示
- D. 补码中 0 只有一种表示
答案与解析
答案:D
原码有 \(+0\) = 00000000、\(-0\) = 10000000 两种;反码有 00000000、11111111 两种;补码中 \(-0\) 的 11111111 + 1 = 00000000 回到 \(+0\)——只有一种。
练习 8 · 10000000 的含义¶
题目
8 位补码 \(10000000\) 表示的数是( )
- A. \(-0\)
- B. \(-127\)
- C. \(-128\)
- D. \(128\)
答案与解析
答案:C
补码里没有 \(-0\):省下的 10000000 分给 \(-128\)。若按无符号解读它才是 \(128\)——先看题目问的是哪种编码。
练习 9 · 8 位补码范围¶
题目
8 位补码能表示的整数范围是( )
- A. \(-127 \sim 127\)
- B. \(-128 \sim 127\)
- C. \(-128 \sim 128\)
- D. \(-127 \sim 128\)
答案与解析
答案:B
套公式 \([-2^{7},\ 2^{7}-1] = [-128,\ 127]\)。A 是原码的范围(原码表示不了 \(-128\))。
练习 10 · 减法变加法¶
题目
用 8 位补码计算 \(3 - 5\),结果的补码是( )
- A. \(11111110\)
- B. \(10000010\)
- C. \(11111100\)
- D. \(00000010\)
答案与解析
答案:A
\(3\) = 00000011,\(-5\) 的补码 = 11111011;相加 = 11111110(无进位),它就是 \(-2\) 的补码。
练习 11 · 16 位补码最小值¶
题目
16 位补码能表示的最小整数是( )
- A. \(-32767\)
- B. \(-32768\)
- C. \(-32769\)
- D. \(-65536\)
答案与解析
答案:B
最小值 = \(-2^{15} = -32768\)(即 1000000000000000)。
练习 12 · 同一串二进制的两种解读¶
题目
二进制 \(10000000\) 作为无符号数和作为 8 位补码,分别是( )
- A. \(128\) 和 \(-0\)
- B. \(128\) 和 \(-128\)
- C. \(256\) 和 \(-128\)
- D. \(-128\) 和 \(128\)
答案与解析
答案:B
无符号:最高位也是数值位,\(10000000 = 128\);补码:最高位是符号位,表示 \(-128\)。同一串 bit,解读规则不同结果不同。
练习 13 · 补码(正数)求真值¶
题目
8 位补码 \(01101010\) 表示的十进制数是( )
- A. \(106\)
- B. \(-106\)
- C. \(104\)
- D. \(96\)
答案与解析
答案:A
符号位是 0 → 正数,三码相同,直接按权展开:\(64+32+8+2 = 106\)。
干扰项:B 见 1 多就把负号扣上来;C 漏加末位的 \(2\)。
练习 14 · 补码(尾零型)求真值¶
题目
8 位补码 \(11110000\) 表示的十进制数是( )
- A. \(-15\)
- B. \(-240\)
- C. \(240\)
- D. \(-16\)
答案与解析
答案:D
快捷法:从右往左第一个 1 在第 5 位,它和右边 10000 不动,左边(符号位除外)1110 取反成 0001 → 原码 10010000 = \(-16\)。
干扰项:C 按无符号算(\(11110000 = 240\));B 无符号值还扣错负号;A 多减了一个 1。
练习 15 · 求 −2 的补码¶
题目
\(-2\) 的 8 位补码是( )
- A. \(10000010\)
- B. \(11111101\)
- C. \(11111110\)
- D. \(11111111\)
答案与解析
答案:C
原码 10000010 → 反码 11111101 → 加 1 → 11111110。
干扰项:B 是反码(忘加一);A 是原码;D 是 \(-1\) 的补码(多加了一次 1)。
练习 16 · 求负数的反码(−7)¶
题目
\(-7\) 的 8 位反码是( )
- A. \(11111000\)
- B. \(11111001\)
- C. \(10000111\)
- D. \(11110111\)
答案与解析
答案:A
原码 10000111 → 符号位不动、数值位取反 0000111 → 1111000 → 反码 11111000。
干扰项:B 是补码(反码多加了 1);C 是原码。
练习 17 · 8 位原码的范围¶
题目
8 位原码能表示的整数范围是( )
- A. \(-128 \sim 127\)
- B. \(-127 \sim 127\)
- C. \(-128 \sim 128\)
- D. \(-127 \sim 128\)
答案与解析
答案:B
原码负数最小是 11111111 = \(-127\);\(-0\) 与 \(+0\) 占两个编码但值相同,\(-128\) 的原码需要 9 位,写不下。
干扰项:A 是补码的范围——原码没有把 \(-0\) 的编码让给 \(-128\)。
练习 18 · 正数与负数的个数¶
题目
8 位补码中,负数与正数分别有( )个。
- A. \(127\) 与 \(127\)
- B. \(127\) 与 \(128\)
- C. \(128\) 与 \(128\)
- D. \(128\) 与 \(127\)
答案与解析
答案:D
负数 \(-128 \sim -1\) 共 \(128\) 个;正数 \(1 \sim 127\) 共 \(127\) 个;\(0\) 单独占一个编码。
干扰项:C 忘了 \(0\) 也占掉一个编码(总数 \(256 = 128 + 1 + 127\))。
练习 19 · 编码总数¶
题目
n 位二进制编码一共能表示( )个不同的数。
- A. \(2^{n-1}\)
- B. \(2^{n}-1\)
- C. \(2^{n}\)
- D. \(2^{n}+1\)
答案与解析
答案:C
每一位 2 种取值,共 \(2^n\) 个编码。8 位 = \(256\) 个:\(128\) 个负数 + \(1\) 个零 + \(127\) 个正数。
干扰项:B 把“最大值 \(2^n - 1\)”当成了个数。
练习 20 · 快捷法正向(原码 → 补码)¶
题目
原码 \(10011001\)(\(-25\))直接用快捷法求补码,结果是( )
- A. \(11100110\)
- B. \(11100111\)
- C. \(01100110\)
- D. \(11101001\)
答案与解析
答案:B
从右往左第一个 1 在末位:它不动,左边除符号位外取反 \(001100 \to 110011\) → 补码 11100111,与“反码 + 1”结果一致。
干扰项:A 只做了取反(那是反码);C 符号位跟着一起翻了。
练习 21 · 溢出演算¶
题目
用 8 位补码计算 \(100 + 50\),结果的补码与真值是( )
- A. 补码 \(10010110\),真值 \(-106\)
- B. 补码 \(10010110\),真值 \(150\)
- C. 补码 \(10010111\),真值 \(151\)
- D. 补码 \(01110110\),真值 \(118\)
答案与解析
答案:A
\(100\) = 01100100,\(50\) = 00110010,相加 = 10010110——最高位变成 1,按补码解读是负数:数值位取反加一得 1101010,原码 11101010 = \(-106\)。\(150 > 127\) 超出范围,溢出后正数变负数。
干扰项:B 结果位串对了,但最高位已经是符号位,不能当正数读。
练习 22 · 补码 10000001 的真值¶
题目
8 位补码 \(10000001\) 表示的十进制数是( )
- A. \(-1\)
- B. \(-127\)
- C. \(-128\)
- D. \(129\)
答案与解析
答案:B
数值位取反 0000001 → 1111110,加 1 = 1111111 = \(127\) → 原码 11111111 = \(-127\)。
干扰项:A 把它当原码读(原码 10000001 才是 \(-1\));D 按无符号读。
练习 23 · 最大正数的补码¶
题目
8 位补码能表示的最大正数的补码是( )
- A. \(01111110\)
- B. \(11111111\)
- C. \(10000000\)
- D. \(01111111\)
答案与解析
答案:D
符号位为 0、数值位全 1:\(01111111 = 2^7 - 1 = 127\)。
干扰项:B 是 \(-1\)(全 1 在补码里是负数);C 是 \(-128\)。
练习 24 · 无符号整数最大值¶
题目
32 位无符号整数(unsigned int)能表示的最大值是( )
- A. \(2147483647\)
- B. \(2147483648\)
- C. \(4294967295\)
- D. \(4294967296\)
答案与解析
答案:C
无符号 32 位范围 \([0,\ 2^{32}-1]\),最大值 \(= 4294967295\)。
干扰项:A 是有符号 int 的最大值;D 是编码总数 \(2^{32}\),最大值要少 1。
练习 25 · 为什么用补码¶
题目
计算机内部用补码存储整数的主要原因是( )
- A. 可以省掉符号位,多表示一倍的数
- B. 减法可以转化为加法,且 0 的表示唯一
- C. 补码的形式更短,节省存储空间
- D. 补码可以直接支持乘法和除法
答案与解析
答案:B
补码把 \(a - b\) 变成 \(a + (b\text{ 的补码})\),CPU 只需一套加法器;同时 0 只有唯一编码,多出的编码表示 \(-128\)。
干扰项:A 符号位依然存在(最高位);C/D 与补码的动机无关。
历年真题¶
2024 年 · 第 1 题¶
题目
32 位 int 类型的存储范围是?( )
- A. \(-2147483647 \sim +2147483647\)
- B. \(-2147483647 \sim +2147483648\)
- C. \(-2147483648 \sim +2147483647\)
- D. \(-2147483648 \sim +2147483648\)
答案与解析
答案:C
32 位补码范围 \([-2^{31},\ 2^{31}-1] = [-2147483648,\ 2147483647]\)。负数比正数多一个——A 是“正负对称”的直觉错误。
易错小结¶
- 正数三码相同,别多做一步“取反加一”;
- \(-1\) 的补码是全 1(
11111111),全 1 不是 \(-127\)/\(-128\); - 补码里没有 \(-0\):
10000000表示 \(-128\)(负数多一个的来源); - 补码 ↔ 原码来回用同一套操作:取反加一,或“从右往左第一个 1 及其右边不动、左边(符号位除外)取反”;
- 范围题记“负多正少”:8 位 \(-128 \sim 127\)、16 位 \(-32768 \sim 32767\)、32 位
int\(-2147483648 \sim 2147483647\)。