Appearance
真值与机器数:四种编码的定义
2026 大纲 二(一)2 定点数的编码表示 · 二(三)整数的表示和运算。二(三)的无符号整数与带符号整数,正是本篇中"纯二进制"与"补码"两种编码在整数上的落地。
机器里没有"负号"这个符号
真值是带正负号的实际数值,是人写的形式;机器数是连符号一起编码成 0/1 位串的形式。机器里根本没有"
于是问题变成:符号编进去之后,怎么让它别碍事?四种编码回答的都是同一个问题——
🔴 符号位数字化之后,能不能和数值部分一起参加运算? 不能,就得先取符号、比绝对值、再决定做加还是做减;能,加法器直接把
位一起加就完了。四种编码的差别只在负数怎么编——正数在原码、反码、补码三者中完全相同。
补码之所以成为整数的通用表示,理由只有一条:
🔴 它能用加法做减法,根据是模运算。
位寄存器丢弃进位等价于对 取模,于是 ,而 正是 。顺带一提,"取反加 1"不是口诀,它是定义式 的代数展开(见下方折叠块)。
⚠️ 读定义式前先确认一件事:本篇的
一、四种编码的定义式与表示范围
原码:符号位取真值的正负(正 0 负 1),数值位直接写绝对值。
式中
补码:正数与原码相同;负数是反码加 1。
范围
反码:正数与原码相同;负数是原码的数值位按位取反(符号位不变)。范围与原码相同。它现在几乎不单独使用——从"取反加 1"的推导可以看出它的真实身份:它就是
移码:在真值上加一个偏置常数(这里取
范围与补码相同。
⚠️ IEEE 754 的阶码也是移码,只是偏置常数不取
而取 (单精度 127、双精度 1023)。别把"移码的最小真值对应全 0"与"IEEE 754 里阶码全 0 有特殊含义"混为一谈——后者是标准对特殊值的编码约定,与移码本身的性质无关。
⚠️ 还有一条前提要说死:只给一串位是确定不了真值的,还必须知道用的是哪种编码和字长是多少。同一个真值在不同位数下机器数不同(
在 位下是 10...0、在位下是 110...0),同一串位在不同编码下真值也不同。
补码为什么能把减法变成加法,以及"取反加 1"的代数展开(想弄清这两条是推出来的而不是硬记的时展开)
模运算。 钟表是个模 12 的系统:时针从 10 点倒拨 4 格,可以逆时针拨 4 格(
只要用
"取反加 1"的来历。 定义式里是
拆项之后一目了然:
用一个数把"定义式"和"取反加 1 操作"对上号。 取 8 位、真值 0101101:
| 编码 | 结果 | 怎么来的(操作路径) |
|---|---|---|
| 原码 | 10101101 | 符号位 1 + 绝对值 |
| 反码 | 11010010 | 原码数值位取反 |
| 补码 | 11010011 | 反码加 1 |
| 移码 | 01010011 | 补码符号位取反 |
再走定义式这条路,两边必须落到同一串位:
- 补码定义式
: ✓ - 移码定义式
: ✓
操作路径与定义式给出同一个结果——这正是上面那段代数展开所证明的事。手算时用操作路径快,判断边界或位数变化时回到定义式才靠得住。
二、四位字长的全表
| 真值 | 原码 | 反码 | 补码 | 移码 |
|---|---|---|---|---|
| +7 | 0111 | 0111 | 0111 | 1111 |
| +6 | 0110 | 0110 | 0110 | 1110 |
| +5 | 0101 | 0101 | 0101 | 1101 |
| +4 | 0100 | 0100 | 0100 | 1100 |
| +3 | 0011 | 0011 | 0011 | 1011 |
| +2 | 0010 | 0010 | 0010 | 1010 |
| +1 | 0001 | 0001 | 0001 | 1001 |
| +0 | 0000 | 0000 | 0000 | 1000 |
| −0 | 1000 | 1111 | — | — |
| −1 | 1001 | 1110 | 1111 | 0111 |
| −2 | 1010 | 1101 | 1110 | 0110 |
| −3 | 1011 | 1100 | 1101 | 0101 |
| −4 | 1100 | 1011 | 1100 | 0100 |
| −5 | 1101 | 1010 | 1011 | 0011 |
| −6 | 1110 | 1001 | 1010 | 0010 |
| −7 | 1111 | 1000 | 1001 | 0001 |
| −8 | — | — | 1000 | 0000 |
看最后两行:
三、还有一种"第零号编码":无符号数
上面四种回答的都是"符号怎么编"。如果一个量根本不会为负(地址、计数值、位串本身),就没必要留出符号位——
它与补码的关系就是最高位权的差别:补码把最高位的权取成 11111111 按补码是
| 编码 | 负数怎么编 | 零 | 表示范围( | 主要用途 |
|---|---|---|---|---|
| 无符号 | 不表示负数 | 唯一 | 地址、计数、位串 | |
| 原码 | 符号位 1 + 绝对值 | 两个 | 乘除法的数值部分、浮点尾数 | |
| 反码 | 原码数值位取反 | 两个 | 求补码的中间步骤 | |
| 补码 | 反码 + 1 | 唯一 | 整数的通用表示、加减运算 | |
| 移码 | 补码符号位取反 | 唯一 | 浮点数的阶码 |
这张表里有三处不是巧合:
🔴 零的表示:原码 / 反码各两个,补码 / 移码唯一。
, 。
🔴 补码为什么比原码、反码多一个数:原码与反码各浪费了一个位串在
上。 位一共 个位串是定死的,少一个零就能多一个数,空出来的那个给了 。所以范围的不对称不是设计缺陷,是消除冗余的必然结果。左右不对称的算法也随之清楚:正数 个、负数 个、零 1 个,加起来正好 ——零被算进了非负那一侧,所以负数多一个。
🔴 移码
补码的符号位取反,这个改动的用意是:加偏置之后最小真值映射到全 0、最大真值映射到全 1,中间严格单调递增,于是"真值的大小顺序"与"把位串当无符号整数读的顺序"完全一致——浮点比大小时硬件直接按位串比就行。补码做不到这一点:补码里 是全 1,按无符号读反而是最大值。
一句话选型:要按位串直接比大小就用移码,要让符号位参与加法就用补码。 阶码需要前者,整数需要后者。
四、按权展开:把符号位当成一个负权
前面的分段定义适合"给真值求编码"。反过来"给一串位求真值",用按权展开更快——只要把最高位的权取成负的:
8 位的具体形态是
| 位串 | 展开 | 真值 |
|---|---|---|
10000000 | ||
10000001 | ||
11111111 |
🔴 由位串求真值,走按权展开最快。 口诀是:符号位为 1 时,真值
再加上低 位当无符号数读出的值。位串里 1 越多,这条路越省事。
🔴 顺带澄清一个常见误解:
10000000不是溢出。 8 位补码的范围是, 是合法值。"求补必溢出"说的是对它做求补运算会溢出( 超出上界),不是它本身非法。
这个式子怎么来的,以及用它构造"含 k 个 1 的最小补码"(碰到给 1 的个数求极值这类题、或想确认它对正数也成立时展开)
设最高位
正是上式。
用它构造极值。 问:由 3 个 1 和 5 个 0 组成的 8 位二进制补码,能表示的最小整数是多少?
- 定符号位。要最小(最负),符号位必须是
1——符号位为 0 的都是非负数,一定比它大。用掉一个1。 - 写出展开式。符号位为 1
真值 。 - 最小化剩下的部分。低 7 位还剩 2 个
1和 5 个0,要让它作为无符号数尽可能小,就把两个1全塞到最低位:0000011。
第 3 步为什么不能随手放:满足"3 个 1"的位串不止一个,11100000 同样有 3 个 1,但两个 1 摆在高位,低 7 位读出来是 96,真值
考点速记
- 四种编码是对"符号位能否参加运算"的四种回答,差别只在负数怎么编;零的表示是原码/反码各两个、补码/移码唯一,补码多出的
正是从 那里省下来的。 - 补码能用加法做减法的原因是模运算(
位寄存器丢弃进位等价于对 取模),"取反加 1"是定义式 的代数展开,不是口诀。 - 移码
补码符号位取反,它把真值顺序映射成无符号数顺序,所以用于阶码;由位串求真值走按权展开(最高位取负权)最快;给定编码必须交代编码方式和位数,否则边界问题无解。
这一节在真题里被考过的形式(下方「真题练习」里属于本篇的那几道):
- 给一个十进制真值,问它的机器数(十六进制):正数直接转;负数走
或"取反加 1",算完用按权展开验一遍。⚠️ 位数按题面给的类型定( short是 16 位),别按 32 位算。 - 给机器数问真值,并接着做一次加减:先按权展开求出两个真值(最高位取负权最快),算完再编码回去。这类题通常在第二问上设溢出陷阱。
- 给几个机器数,问按无符号 / 按带符号解释时的大小关系:同一串位在两种解释下的顺序可以完全不同。按无符号就直接比位串;按带符号先看最高位——负数一律小于非负数,都是负数时再比。这道题考的正是"补码顺序
位串顺序"。 - 给一个机器数,问它按 int 或按 float 解释时的值可能是多少:把同一串位分别按补码和 IEEE 754 各读一遍,看哪个选项对得上。这是"位串本身没有类型"的最直接考法。
- 问由若干个 1 和若干个 0 组成的
位补码能表示的最小整数:要最小就要最负,所以符号位必须是 1,剩下的 1 尽量往低位放(数值部分越小越负)。
易错:把补码的表示范围写成左右对称。负数比正数多一个,因为零算在非负那侧。
易错:按无符号的顺序去比补码的大小。补码里全 1 是
而不是最大值。
易错:位数按 32 位默认算。
short是 16 位,题面给什么类型就用什么位数。
易错:把"取反加 1"当成孤立口诀。它就是
,拿不准时回到定义式。
教材出处
- 四种编码的定义式与表示范围:唐朔飞《计算机组成原理》第 3 版 §6.1 无符号数和有符号数,印刷页 p223–p228(含表 6.1 全位串对照表、图 6.1 移码数轴)
- 模运算动机(钟表模 12 的例子)与"取反加 1"的代数展开:袁春风《计算机组成与系统结构》第 3 版 §2.1.4 定点数的编码,印刷页 p29–p31
在 位与 位下机器数不同、给定编码必须明确位数:同书 §2.1.4 例 2.12,印刷页 p30
相关知识
定点数编码的转换与书写|补码加减运算与溢出判别|浮点数表示(IEEE 754)