Skip to content

定点数编码的转换与书写

2026 大纲 二(一)2 定点数的编码表示(同时是 二(三)整数的表示和运算 的地基)。四种编码的定义式与表示范围见 真值与机器数,本篇只管动手

真值、二进制、十六进制是同一个数的三种写法

511111011FBH 说的是同一件事:真值是人理解的形态,二进制机器数是机器里的真实形态,而十六进制只是二进制的书写压缩——一位十六进制严格等于四位二进制,两者之间的转换只是分组不产生任何计算

这一节讲的就是这几种形态之间怎么走。整条路线可以画成一张图:

交互可视化

加载可视化中...

一、三种形态之间的路

真值 → 机器数,以 5、8 位补码为例:

  1. 取绝对值转二进制:|5|=5=(101)2,补足 7 位数值位 → 0000101
  2. 写原码:符号位 1 → 10000101
  3. 数值位取反 → 11111010(反码)
  4. 末位加 1 → 11111011(补码)
  5. 四位一组转十六进制:1111 1011FBH

机器数 → 真值:符号位是 0 就直接按无符号读;是 1 则再求一次补(数值位取反加 1)得到绝对值,再添负号。以 11001100 为例:符号位 1,是负数;数值位 1001100 取反得 0110011,加 1 得 0110100 =52,所以真值 =52,十六进制写作 CCH

十六进制 ↔ 二进制,四位一组机械对应:

HexBinHexBinHexBinHexBin
000004010081000C1100
100015010191001D1101
2001060110A1010E1110
3001170111B1011F1111

🔴 四位一组要从最低位往高位分,不足的在高位补 0。定点整数这样分才对得上权重。

⚠️ 位数是编码信息的一部分。 不交代位数,FBH 到底是 8 位还是 16 位截出来的一段就说不清;同一真值在不同位数下机器数不同。所以机器数一律用十六进制书写时,位数信息必须一起写明

二、两条捷径为什么成立

手算时有两条捷径能省不少步骤,但它们各自有适用边界。

捷径一:扫描法,把"取反"和"加 1"合并成一步——从最低位向左扫描,找到第一个 1;该位及其右侧全部不变,左侧逐位取反。 它在原码 ↔ 补码之间双向可用,两个方向规则完全相同。

🔴 扫描法的输入不能是反码。 它合并的正是"取反"和"加 1"两步;手里已经是反码就只差加 1 了,再去扫描等于把取反做了两遍。动手之前先确认手上这串位处在链条的哪一环。

捷径二:求相反数连符号位一起取反加 1,即 [X]=[X]+1,取反范围含最高位。这里要和"由补码求原码"分清楚:

🔴 "换编码"与"换数"动的位不一样。[X][X]只取反数值位、符号位保持,结果是同一个数的另一种编码;由 [X][X]全部位取反、含符号位,结果是另一个数。一句话记:换编码不换数,符号位不动;换数不换编码,符号位跟着翻。

另外"取反加 1"是个自逆运算——对同一个补码位串做两次会回到原位串。所以它输入负数的原码数值位就输出补码数值位,输入负数的补码数值位就输出绝对值

🔴 唯一的例外是最小负数:2n1 没有相反数。 对它求补得到的还是它自己(+2n1 超出了上界),硬件会置溢出标志。这是补码表示范围左右不对称留下的唯一破绽。

顺带记三个任意位数下都成立的边界形态:1 的补码是全 F(FFH / FFFFH / FFFFFFFFH);最小负数是 8 后面跟全 0(80H / 8000H / 80000000H);最大正数是 7 后面跟全 F(7FH / 7FFFH)。

扫描法与"连符号位取反"各自的证明,以及三行对照表(想弄清进位链为什么恰好在第一个 1 处终止、或不放心"符号位也要翻"时展开)

扫描法为什么成立:设位串低端形如 x1000。加 1 时,末尾的连续 0 全部被"取反"的结果本来是连续 1,加 1 后又全部进位变回 0;第一个 1 被取反成 0,进位再把它变回 1。进位链恰好在第一个 1 处终止,所以从该位往右一切原样,往左只剩取反。

用它把补码 11001100 转回原码:

1|100取反1第一个 1100不变1|0110100

数值位 0110100=52,真值 52,与取反加 1 的结果一致。

求相反数为什么连符号位:补码的定义是模 2n 下的余数,[X]+[X]0(mod2n),即 [X]=2n[X]。而 2nA=(2n1A)+1,其中 2n1全 1,用全 1 减 A 就是把 A每一位(含最高位)翻转。所以取反的范围天然覆盖符号位。而"由补码求原码"是在已知符号的前提下还原绝对值,符号位是已经定好的信息,不参与运算。

[X]全位取反加 1[X]真值对照
01001100+761011010076
110011005200110100+52
1000000012810000000仍是 128(求补溢出)

最后一行不是笔误:+128 根本无法用 8 位补码表示(上界 +127)。推广到任意位数,最小负数 2n1 没有相反数

三个边界形态的原因也不难看出:1 的补码是 2n1,即全 1;最小负数 2n1 的补码是 2n2n1=2n1,即最高位为 1、其余全 0。

三、同一串位的两种读法

位模式不变,解释方式变。 一串 8 位 10000110

怎么读算法
无符号数134128+4+2=134,最高位就是数值位
补码122最高位是符号位,134256=122

两个值相差正好 28=256,这不是巧合:

补码值=无符号值2n(最高位为 1 时)

机器并不知道该读哪个,也不需要知道——读法由指令决定,位串本身不带类型。寄存器里只有电平:无符号加法与带符号加法指令算出同一串结果位,区别只在置哪些标志、溢出如何判定。高级语言里同理,intunsigned int 变量在内存里的位一模一样,是编译器根据声明选择了不同的指令。

🔴 比较大小时最容易翻车FFFDH 按 16 位补码是 3、按无符号是 65533,大小关系完全相反。所以这类题一定要先看清题面问的是哪种解释。

考点速记

  1. 真值、二进制机器数、十六进制机器数是同一个数的三种写法,后两者之间只是分组、不产生计算;四位一组从最低位往高位分,机器数用十六进制书写时位数信息必须一起写明
  2. 扫描法把"取反"和"加 1"合并成一步,在原码 ↔ 补码双向可用、不能用在反码上;求 [X]连符号位一起取反加 1,由补码求原码则只动数值位;最小负数 2n1 求补必溢出。
  3. 同一位串按无符号与按补码读,最高位为 1 时相差 2n读法由指令决定,位串本身不带类型

这一节在真题里被考过的形式(下方「真题练习」里属于本篇的那几道):

  • n 位补码所能表示的整数范围[2n1, 2n11]。左右不对称,负数比正数多一个——多出来的那个是从 0 省下来的,理由见 四种编码的定义
  • 问由指定个数的 1 和 0 组成的 n 位补码能表示的最小整数:分两步——要最负,符号位必须是 1(用掉一个 1);剩下的 1 全部塞到最低位让低 n1 位的无符号值尽可能小,再套 X=2n1+(低位值)。⚠️ 满足"几个 1"的位串不止一个,约束限定个数、最小化要求往低位摆,两件事要分开想。

易错:把扫描法用在反码上。它已经含了"取反"这一步。

易错:求相反数时只翻数值位。换数要连符号位一起翻,换编码才只动数值位。

易错:认为 2n1 也有相反数。对它求补会溢出。

易错:把补码范围写成左右对称。负数多一个。

教材出处
  • 模运算与补码定义、"取反加 1"的代数展开:袁春风《计算机组成与系统结构》第 3 版 §2.1.4 定点数的编码,印刷页 p29–p31
  • "机器数一定是一个 0/1 序列,通常缩写成十六进制形式":同书 §2.1.4,印刷页 p28
  • 同一真值在不同位数下机器数不同,给定编码必须明确位数:同书 §2.1.4 例 2.12,印刷页 p30
  • [Y][Y] 需连同符号位取反末位加 1:唐朔飞《计算机组成原理》第 3 版 §6.1,印刷页 p226

相关知识

真值与机器数:四种编码的定义进位计数制与转换补码加减运算与溢出判别

真题练习