精简版 · 小杯2026-08 冻结,已停止更新(发布前修订了 4 处已知错误)。后续勘误与新增内容只在正式版。看正式版(中杯)→
Skip to content

真值与机器数:四种编码的定义

大纲定位

二(一)2 定点数的编码表示

要求:掌握原码、反码、补码、移码四种编码的定义、表示范围与零的表示。本篇是定义篇;具体怎么转、卷面怎么写,见 定点数编码的转换与书写

考情分析

408 的题型只有单项选择题综合应用题两类。本考点是整章的地基——补码加减、溢出判断、IEEE 754 全建立在它之上。选择题里最常出现的是边界值辨析(最小负数、±0、同一位串的不同解释)。

全篇符号约定

本篇统一用 n 表示机器字长(含 1 位符号位),数值位有 n1 位。

有些教材用 n 表示数值位数,其定义式会写成 [X]=2n+1+X。两套约定都对,但代进表示范围时会差一位,看书时先确认这本书的 n 是哪个

真值与机器数

真值:带正负号的实际数值,如 +10110.1101。人写的形式。

机器数:连符号一起编码成 0/1 位串放进寄存器的形式。机器里没有"负号"这个符号,正负必须编码进去。

把真值变成机器数有四种编码方式:原码、反码、补码、移码。它们的差别只在负数怎么编——正数在四者中除移码外完全相同。

原码

符号位取真值的正负(正 0 负 1),数值位直接写绝对值。

[X]={X0X<2n12n1+|X|2n1<X0

式中 2n1+|X| 就是"把符号位置 1、数值位保持绝对值"。

表示范围(2n11)+(2n11)

零有两个[+0]=000[0]=100

原码的好处是直观、乘除方便;坏处是加减法要先比较绝对值再决定做加还是做减,硬件麻烦——这正是补码出现的动机。

反码

正数与原码相同;负数是原码的数值位按位取反(符号位不变)。

表示范围:与原码相同,(2n11)+(2n11)

零也有两个[+0]=000[0]=111

反码现在几乎不单独使用,它的主要角色是求补码的中间步骤

补码

正数与原码相同;负数是反码加 1。

[X]={X0X<2n12n+X2n1X<0

表示范围2n1+(2n11)——比原码/反码多一个最小负数 2n1

零唯一[+0]=[0]=000。正因为不用再给 0 留一个编码,那个位串腾出来给了 2n1

补码为什么能用加法做减法

关键在模运算。钟表是个模 12 的系统:时针从 6 点拨到 3 点,可以逆时针拨 3 格(3),也可以顺时针拨 9 格(+9)——因为 39(mod12),两者等效。

n 位寄存器就是一个模 2n 的系统:超出 n 位的进位自动丢弃,等价于对 2n 取模。所以

XYX+(2nY)(mod2n)

只要用 2nY 这个"补数"代替 Y减法就变成了加法。而 2nY 正是 [Y] 的定义。

"取反加 1" 是怎么来的

定义式里是 2n+XX 为负),实际操作却是"取反加 1",两者为什么等价?以 8 位、|X|=1101100 为例:

281101100=10000000符号位+(11111111101100)数值位按位取反+1末位加 1

拆项之后一目了然:$1111111 - $ 数值位就是逐位取反(因为每一位不是 0 就是 1,用 1 减等于翻转),剩下那个 1 就是末位加 1。所以"取反加 1"不是硬记的口诀,是定义式的直接展开。

移码

[X]=2n1+X(2n1X<2n1)

即在真值上加一个偏置常数(这里取 2n1)。等价的快捷说法:移码 = 补码的符号位取反

表示范围:与补码相同,2n1+(2n11)零唯一

移码的用处是便于比较大小:真值越大,移码作为无符号整数读出来的值也越大,顺序完全一致。所以浮点数的阶码采用移码,比较两个浮点数的大小时可以直接按位串比。

移码与 IEEE 754 的偏置常数

IEEE 754 的阶码同样是移码,只是偏置常数不取 2n1 而取 2n11(单精度 127,双精度 1023)。

不要把"移码最小真值对应全 0"与"IEEE 754 阶码全 0 有特殊含义"混为一谈——后者是标准对特殊值的编码约定(阶码全 0 表示 ±0 或非规格化数,全 1 表示 或 NaN),与移码的性质无关。详见 IEEE 754 浮点数表示

四位编码全表

把 4 位字长下的所有位串列全,四种编码的差异一眼可见:

真值原码反码补码移码
+70111011101111111
+60110011001101110
+50101010101011101
+40100010001001100
+30011001100111011
+20010001000101010
+10001000100011001
+00000000000001000
−010001111
−11001111011110111
−21010110111100110
−31011110011010101
−41100101111000100
−51101101010110011
−61110100110100010
−71111100010010001
−810000000

看最后两行:8 只有补码和移码能表示,原码/反码的那个位串被 0 占用了。

四种编码对比

编码负数怎么编表示范围(n 位含符号)主要用途
原码符号位 1 + 绝对值两个[(2n11), 2n11]乘除法的数值部分
反码原码数值位取反两个[(2n11), 2n11]求补码的中间步骤
补码反码 + 1唯一[2n1, 2n11]整数的通用表示、加减运算
移码补码符号位取反唯一[2n1, 2n11]浮点数的阶码

边界值:最容易出选择题的地方

2n1 是补码独有的,它没有对应的原码和反码

由此派生出三个必须分清的位串(以 8 位为例):

位串按补码读说明
10000000128补码最小值。它的相反数 +128 无法用 8 位补码表示
10000001127补码最小值加 1
111111111全 1。不是 127、也不是 128

两个陷阱

  1. 128 不是溢出。8 位补码范围是 [128,+127]128合法值,机器数 10000000。别一看到它就判溢出。
  2. 给定编码必须说清位数。同一个真值在不同位数下机器数不同;题目不给字长,[2n1] 这类边界题根本无法作答。

补码的按权展开:把符号位当成一个负权

前面的分段定义适合"给真值求编码"。反过来"给一串位求真值",用按权展开更快——只要把最高位的权取成负的

X=bn12n1+i=0n2bi2i

也就是说,n 位补码里最高位的权是 2n1,其余各位的权照常是正的。

8 位的具体形态

X=128b7+64b6+32b5+16b4+8b3+4b2+2b1+b0

用它验算前面那三个位串:

位串展开真值
10000000128+0128
10000001128+1127
11111111128+1271

一句话记法

符号位为 1 时,真值 = 2n1 加上低 n1 位当无符号数读出的值。

这比"取反加一再添负号"快得多,尤其是位串里 1 很多的时候。

用它构造极值

有一类题不给具体数,只给"位的个数"限制,要你找出最大/最小值。按权展开是唯一顺手的工具。

:由 3 个 1 和 5 个 0 组成的 8 位二进制补码,能表示的最小整数是多少?

  1. 定符号位。要最小(最负),符号位必须是 1——符号位为 0 的都是非负数,一定比它大。用掉一个 1
  2. 写出展开式。符号位为 1 真值 =128+(低 7 位的无符号值)
  3. 最小化剩下的部分。低 7 位还剩 2 个 1 和 5 个 0,要让它作为无符号数尽可能小,就把两个 1 全塞到最低位0000011 =3
Xmin=128+3=125,机器数 10000011

干扰项各自错在哪,值得逐个看一眼——它们代表三种不同的走神方式:

干扰项对应位串问题
12610000010只有 2 个 1不满足"3 个 1"的条件
3111111017 个 1,同样不满足
32111000001 的个数是对的(3 个),但它不是最小——两个 1 摆在高位,低 7 位读出来是 96,128+96=32,比 125 大得多

32 这个干扰项最有价值:它提醒你满足条件的位串不止一个,题目要的是其中最小的那个。所以第 3 步"把 1 全塞到最低位"不是随手一放,而是最小化那一项的唯一方式。

典型例题

例 1:8 位(含符号位),写出 45 的原码、反码、补码、移码。

45=(101101)2,7 位数值位写作 0101101

编码结果怎么来的
原码10101101符号位 1 + 绝对值
反码11010010原码数值位取反
补码11010011反码加 1
移码01010011补码符号位取反

验证补码:2845=211=(11010011)2

例 2:8 位补码能表示的最小负数与最大正数分别是多少?

最小 27=12810000000),最大 271=+12701111111)。注意负边界的绝对值比正边界大 1,这是补码的固有不对称。

例 3:由 3 个 1 和 5 个 0 组成的 8 位补码,能表示的最小整数是多少?

要最小(最负),符号位必须是 1(占掉一个 1)。剩下 2 个 1 放在数值位——负数补码的数值位越小、真值越负,所以两个 1 尽量往低位放:10000011

真值 =3128=125

考点清单

  • [ ] 真值与机器数的区别:符号是否被编码进位串
  • [ ] 四种编码的定义式与表示范围
  • [ ] 零的表示:原码/反码各两个,补码/移码唯一
  • [ ] 补码比原码/反码多表示一个 2n1,因为省下了 0 的编码
  • [ ] 补码能用加法做减法的原因是模运算;"取反加 1"是定义式 2n+X 的展开
  • [ ] 移码 = 补码符号位取反,用于阶码,因为它可直接按无符号比大小
  • [ ] IEEE 754 阶码也是移码,但偏置常数取 2n11
  • [ ] 边界辨析:10000000 = 128(合法非溢出)、11111111 = 1
  • [ ] 给定编码必须交代位数,否则边界题无解

真题练习

教材出处

  • 四种编码的定义式与表示范围:唐朔飞《计算机组成原理》第 3 版 §6.1 无符号数和有符号数,印刷页 p223–p228(含表 6.1 全位串对照表、图 6.1 移码数轴)
  • 模运算动机与"取反加 1"的代数展开:袁春风《计算机组成与系统结构》第 3 版 §2.1.4 定点数的编码,印刷页 p29–p31