跳转至

原码、反码、补码

方法速览

任务 方法 口诀
正数求三码 原码 = 反码 = 补码(符号位 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\) 的三码(分三步)

  1. 写绝对值的 8 位二进制,符号位改 1:\(53 = 0110101_2\) → 原码 10110101
  2. 符号位不变、数值位取反:0101101 → 1010010 → 反码 11001010
  3. 反码末位加 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):

1
2
3
4
  00000101    (+5)
+ 11111101    (−3 的补码)
──────────
1 00000010    丢弃第 9 位进位 → 结果 00000010 = 2

反向 \(3 - 5\)\(-5\) 的补码 = 11111011):

1
2
3
4
  00000011    (+3)
+ 11111011    (−5 的补码)
──────────
  11111110    无进位,结果本身就是 −2 的补码

0 唯一。 原码、反码里 \(+0\)\(-0\) 各占一个编码,判等还要特判;补码里 0 只有一种写法,多出的 10000000 表示 \(-128\)——这就是“负数比正数多一个”的来源。

范围与溢出

n 位补码的范围:

\[[-2^{n-1},\ 2^{n-1}-1]\]

以 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 两种;反码有 0000000011111111 两种;补码中 \(-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\)