第 2 章 运算方法和运算器 —— a 和 b 怎么存、a+b 怎么算
a+b 在这一章:
int a, b;一旦读进来,机器里存的不是”3”和”5”,而是一串二进制补码。a+b这个加法,CPU 其实是用”补码加法”做的,还得防着”算出来溢出了”。这一章就是把”存数”和”算数”两件事彻底讲透——它是全课计算题的最大富矿。
2.1 数据怎么表示
2.1.1 定点数:小数点位置固定
【知识点·定点表示】
- 🎓 定点数约定小数点位置固定不变,常见两种:纯小数(小数点在符号位后)、纯整数(小数点在最低位后);范围受字长限制。
- 🌱 “定点”就是规定好小数点钉死在某个位置不许动,所以叫定点。我们的
int a就是定点纯整数。
定点纯整数: x0 │ x1 x2 ... xn 小数点在最右,符号位 x0 (0正1负)
符号 └── 数值位 ──┘
2.1.2 机器码:原码、反码、补码、移码(本章命根子)
人写的数叫真值(如 +5、−5);存进机器、能让符号也参与运算的叫机器码。
【知识点·原码】
- 🎓 原码:最高位为符号位(0正1负),其余为数值的绝对值;有 +0 和 −0 之分。
- 🌱 就是”符号位 + 绝对值”,最直观,但做减法很麻烦。
- 例:x=+1011 → [x]原=0 1011;y=−1011 → [y]原=1 1011。
【知识点·反码】
- 🎓 反码:正数与原码相同;负数为”原码数值位逐位取反,符号位仍为1”。
- 🌱 负数就是把原码除符号位以外”0变1、1变0”。它是通往补码的中间桥。
- 例:y=−1011 → [y]原=1 1011 → [y]反=1 0100。
【知识点·补码(最重要)】
- 🎓 补码:正数与原码相同;负数 = 反码末位 +1(等价于”模 − |x|”)。定点小数以 2 为模,定点整数以 2ⁿ⁺¹ 为模。补码只有一个 0。
- 🌱 补码是为了”把减法变成加法”发明的。原理就像时钟:现在7点要回到4点,可以−3,也可以+9(因为时钟模12,7+9=16≡4)。负数用”绕一圈补回来”的数代替。
- 例:y=−1011 → [y]反=1 0100 → [y]补=1 0101。
🔥 补码深挖:为什么”减法 = 加法”?—— 一段你必须真正搞懂的原理
为什么单独开这一节? 补码是整本机组里”看起来在背公式、实际有最深漂亮原理”的知识点。教材通常只给”反码+1”的口诀,但口诀背后的”模运算”思想才是 CPU 设计者真正在做的事。理解了它,你看后面所有”硬件用加法器一招解决加减乘除”的设计都会豁然开朗。
问题起点:硬件最怕”减法”。
为什么怕?造一个加法器电路相对简单(一位一位加+进位),但减法要”借位”——硬件得另造一种”借位逻辑”,意味着双倍电路成本。设计师们想:能不能只造加法器,让它顺便也能做减法?
补码就是答案。下面用一个具体的例子,让你亲眼看见它怎么做到的。
第一步:先看”时钟”——理解什么叫”模”
想象一个只有 12 个小时刻度的时钟。现在指针在 7 点,你想让它指到 4 点。有两种走法:
方法 A: 往回拨 3 格 方法 B: 往前拨 9 格
─────────────── ───────────────
7 − 3 = 4 ✓ 7 + 9 = 16
但时钟只有 12 格!
16 转一圈回到 4 ✓
结论:在"12 小时制"里,−3 和 +9 是等价的。
为什么?因为时钟满 12 自动归零——这就是”模 12 运算”。数学上写作:
换句话说:在模 12 的世界里,“减 3” 可以用 “加 9” 代替。9 就是 −3 在模 12 下的”补数”。
🔑 关键洞察:只要一个系统有”模”(满了自动归零),减法就能换成加法。CPU 的字长有限,超出位数的进位会自动丢弃——这恰恰就给了它一个天然的”模”。
第二步:把”时钟模 12”换成”CPU 字长模 2ⁿ”
CPU 的寄存器只有有限位。假设我们做一个很小的 5 位 CPU(一共 5 个晶体管位,先全部按”无符号”理解,等推导跑通了再切到有符号视角),它的”时钟”长这样:
5 位二进制能表示的所有 32 个状态(全部当无符号正整数看):
00000 (0)
00001 (1)
00010 (2)
...
01111 (15)
10000 (16) ← 注意,这是 16,不是 "负数"!现在还是无符号视角
...
11111 (31)
──────────────────────
100000 (这是 32 = 2⁵, 但只有 5 位装不下)
↑
溢出位被硬件自动丢弃 → 实际寄存器里留下 00000
→ 5 位寄存器就像一个 "32 格的圆形时钟"
→ 这台 5 位机器的"模" M = 2⁵ = 32
→ 走到 31 再 +1,自动绕回到 0
这里发生了一件非常重要的事:因为寄存器只装得下 5 位,任何超过 5 位的进位都会被硬件自动扔掉——这就是 5 位机器天然的”满 32 归零”机制。
🔔 重要的视角说明:上面我们把 5 位看成”0~31 的无符号数”。后面同样这 5 位的 11101,会被重新解读为”−3 的补码”——同一串 0/1 在硬件里没有变,变的只是程序员/编译器对它的”解读约定”。这就是补码最绕的地方:0/1 不带正负号,正负是”约定”出来的。我们先用无符号视角把数学跑通,第五步再切到”有符号解读”。
第三步:用真实数字,亲眼看”5 − 3” 变成 “5 + 29”
我们让这台 5 位机器算 5 − 3。按补码思路:
被减数 5 → 二进制 00101
减数 3 → 二进制 00011
想求 5 − 3 = 2 → 期望结果 00010
关键操作:用 32 − 3 = 29 来"代替" −3
29 的二进制 = 11101 ← 这就是 −3 的"补码"
做加法:
00101 (5)
+ 11101 (−3 的补码 = 29)
─────────
100010 ← 一共 6 位
↑↑↑↑↑↑
│
│ 最高位(第 6 位)是溢出,被硬件丢弃!
│
└─→ 实际留在寄存器里的:00010 = 2 ✓
奇迹发生了:硬件只做加法,但因为”满 32 归零”自动把多出来的那一位扔掉,结果正好等于 5 − 3。
🌱 大白话:还是时钟那个例子,5 点想到 2 点,要么往回拨 3(−3,需要减法器),要么往前拨 29(+29,加法器就能干)——两种方式时钟最终指向同一个位置。CPU 选择”+29”这条路,因为它只用一个加法器就能搞定。
第四步:那”29”怎么算出来的?—— 这就是”取反加 1”的真相
我们说 −3 在模 32 下等于 +29。那 29 怎么从 3 算出来?
数学上:M − |x| = 32 − 3 = 29。但 CPU 不能直接算”32 减 3”(这又回到了减法问题)。于是有了一个绝妙的等价变换:
M − |x| = M − 1 − |x| + 1
= (M − 1 − |x|) + 1
└─────────┬───────┘
这部分有个神奇性质 ↓
在 5 位机器里 M − 1 = 31 = 11111 (全 1)
M − 1 − |x| = 11111 − 00011
= 11100 ← 看仔细,这是什么?
就是 00011 的"逐位取反"!
所以:
−3 的补码 = (3 的取反) + 1
= 11100 + 1
= 11101 = 29 ✓
🔍 为什么 “11111 − X” 恰好等于 “X 按位取反”? 看一位真值表就明白:
X 的某位 1 − X 取反 ¬X 0 1−0=1 1 1 1−1=0 0 两列完全一致。所以 “全 1 减一个数” 在硬件上根本不需要减法器——只要给每一位接一个”非门”(NOT,单晶体管就能造,已知最便宜的电路元件)就行。这就是补码”取反加 1”在硬件层面真正廉价的原因。
这就是教材里那句”反码末位加 1 得补码”的真正来源——它不是凭空规定的口诀,而是 “M − |x|” 这个数学事实的硬件友好实现:先全 1 减一下(已证等价于按位取反,只用非门),再 +1(也简单)。
🔑 看到这你应该悟了:补码这套设计是两层抽象:
- 数学层面:负数 ≡ “模 − 绝对值” → 减法变加法
- 硬件实现层面:模 − 绝对值 = 取反 + 1 → 只需”非门 + 加法器”
第五步:把视角切到”有符号”——同一串 0/1 重新解读
第二步留了一个伏笔:“5 位 11101”既可以当无符号 29 用,也可以当有符号 −3 的补码用。这就是切换视角的时刻。
有符号视角的约定:把 0~31 这 32 个状态对半切:
- 00000 ~ 01111 (0 ~ 15) → 当正数 0 ~ +15
- 10000 ~ 11111 (16 ~ 31) → 当负数 −16 ~ −1(每个减 32 得到对应负数——为什么减 32?因为这就是补码的数学定义:有符号真值 = 无符号值 − 模。5 位的模是 2⁵=32,所以
11101的无符号值 29 减 32 = −3,正是我们前面推的 −3 的补码)
无符号视角 有符号(补码)视角
───────── ─────────────────
00000 = 0 0
00001 = 1 +1
...
01111 = 15 +15 ← 正数到此为止
10000 = 16 →切线→ −16 (因为 16 − 32 = −16)
10001 = 17 −15
...
11101 = 29 −3 ← 这就是我们一直在用的 −3 的补码!
11110 = 30 −2
11111 = 31 −1
🔑 同一串 0/1 没有变,变的只是软件怎么”读”它。所以 CPU 加法器根本不知道自己算的是有符号还是无符号——它就是按补码规则做加法、产生进位。“是不是溢出”要软件根据”用哪个视角”自己判断。
补码”只有一个 0”也水落石出:
5 位原码: 5 位补码:
+0 = 0 0000 +0 = 00000
−0 = 1 0000 −0 = ??
↑
取 +0 的补码: 00000 取反 = 11111, +1 = 100000
5 位装不下,溢出丢弃 → 00000
→ −0 的补码 = +0 的补码 = 00000 → 没有独立编码
→ 补码省下了一个编码(原本浪费在 −0 上的那个)
→ 省下来的编码 10000 用来多表示一个原码没有的最小负数:
10000 在切线之后 = 16 − 32 = −16 ← 这就是它怎么算出来的
这就解释了为什么 n 位补码的范围是 −2ⁿ⁻¹ ~ +(2ⁿ⁻¹−1),比原码多一个负数。
一句话装回脑子
补码 = 在”字长有限”自带的”模”下,用加法表示减法的一套统一编码。
一段口诀走天下:“减法→加补码;负数→取反加 1;溢出位→硬件自动丢。”
🌱 大白话回顾整个故事:硬件工程师只想造一种加法器(省钱),数学家说”那行,你只要保证字长有限(自带’模’),我就能让所有减法都化成加法”——然后他发明了”反码+1”这个简单到能用门电路实现的”补数算法”。现代每一颗 CPU 里的减法、负数都是按这个原理跑的。今天你的程序算 5 - 3,CPU 真实做的就是 5 + 11101,然后扔掉溢出位。
真值 → 原码 → 反码 → 补码 的流水线(以 −1011 为例,5位含符号)
−1011
│ 符号位1, 数值取绝对值
[原] 1 1011
│ 负数数值位逐位取反
[反] 1 0100
│ 末位 +1
[补] 1 0101 ← 机器里真正存的就是它
【知识点·已知[x]补求[−x]补(变补/求补)】
- 🎓 [−x]补 = 对[x]补”连同符号位一起每位取反,末位加1”。
- 🌱 想求一个数的相反数的补码?把它的补码整个翻个面再+1。减法时要用到。
【知识点·移码(专用于浮点阶码)】
- 🎓 移码 = 真值 + 偏移量(定点整数定义 [x]移 = 2ⁿ + x);移码与补码数值位相同、符号位相反。
- 🌱 移码就是”把所有数都加一个大数,让它们全变成正数”,这样比较大小特别方便(直接当无符号数比)。所以浮点阶码用它。
- 例:x=+1011111 → [x]补=0 1011111,[x]移=1 1011111(符号位翻转)。
🔑 四码对比记忆:正数四码(除移码外)全相同;负数:原码=符号+绝对值,反码=原码取反,补码=反码+1,移码=补码符号翻转。
【经典例题·−128 之谜】
- n=8 时补码能表示 −128(10000000),但原码/反码表示不了,因为补码”省下了一个 −0 的编码”多表示一个数。范围:补码 −2ⁿ⁻¹ ~ +(2ⁿ⁻¹−1),原/反码 −(2ⁿ⁻¹−1) ~ +(2ⁿ⁻¹−1)。
2.1.3 浮点数与 IEEE754(超高频)
当数字特别大或特别小(电子质量 9×10⁻²⁸ 克),定点就不够用了,要用浮点。
🔥 小白别跳过:为什么是”IEEE 754”,而不是别的什么 754?
1970 年代以前,浮点是一场灾难。每家厂商都自己规定一套浮点格式:IBM 的浮点用 16 进制基数,DEC 用 2 进制但阶码偏移不同,Cray 又另一套……结果是:
- 同一段算法在 IBM 上跑得到 0.1,搬到 DEC 上得到 0.09997(精度不同)
- 程序换机器 = 重写浮点部分(移植灾难)
- 学术论文里 “我的算法误差是 X” —— 别人在另一台机器复现不出来(科学不可重复)
1985 年,IEEE(电气电子工程师协会)第 754 工作组给出了统一标准:所有浮点硬件必须这样实现——符号位、阶码、尾数怎么分;舍入怎么做;溢出/0/NaN 怎么表示。从此整个计算机界的浮点行为第一次可预测、可复现。
🌱 大白话:IEEE 754 = “全世界浮点硬件的普通话”。在它之前是各说各话,之后才有了”我电脑算的 1.5 + 2.7,和你电脑算的位元级完全一致”。
看下面格式时,记住每一条规定都是当年为了对付一个具体的坑而定下来的,不是凭空设计。
【知识点·浮点格式】
- 🎓 浮点数 N = (−1)ˢ × M × Rᴱ,S符号、M尾数、R基数(计算机里R=2隐含)、E阶码。规格化要求尾数最高位有效。
- 🌱 就是科学计数法 1.75 = 1.11×2⁰,把”小数点位置”用阶码记下来,小数点能”浮动”,所以叫浮点。
【知识点·IEEE754 标准(必考,务必背格式)】
单精度 32 位: ┌─┬────────┬───────────────────────┐
│S│ E(8位) │ M(23位) │
└─┴────────┴───────────────────────┘
S: 符号(1位) E: 阶码(移码,偏移127) M: 尾数(原码纯小数,有隐藏的1)
真值 x = (−1)^S × (1.M) × 2^(E−127)
双精度 64 位: S(1) + E(11位,偏移1023) + M(52位)
真值 x = (−1)^S × (1.M) × 2^(E−1023)
- 🎓 IEEE754 中尾数用原码、阶码用移码(便于比较大小);尾数最高位”1”隐藏不存(隐含位);阶码全0表示0/非规格化,全1表示∞/NaN(Not a Number,非数——表示无效运算结果,如 0÷0)。
- 🌱 关键三件事:①符号、阶码、尾数三段;②阶码要”加127再存”;③尾数前面那个”1.”是白送的不占位。
例1(16进制→十进制,课本例):(41360000)₁₆ = 0 10000010 01101100000000000000000 S=0;E=10000010=130,e=130−127=3;1.M=1.0110110=1.011011 x = +1.011011 × 2³ = +1011.011 = (11.375)₁₀
例2(十进制→IEEE754,课本例):(20.59375)₁₀ 20.59375 = 10100.10011 = 1.010010011×2⁴ → e=4,E=4+127=131=10000011 S=0,M=010010011(去掉隐藏1) 结果 = 0 10000011 01001001100000000000000 = (41A4C000)₁₆
🔑 易错:①别忘了阶码偏移(单精度+127);②尾数要去掉/补上隐藏的”1.”;③区分阶码的”移码值E”和真正的”指数e=E−127”。
2.1.4 字符、汉字、校验码
我们的 scanf("%d %d", ...) 里的 "%d" 和空格,都是字符,得用编码存。
【知识点·ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)】
- 🎓 ASCII 用一个字节表示一个字符,低7位编码(128个),最高位常作奇偶校验位。
- 🌱 给每个字母/符号编个号,比如 ‘A’=65、‘0’=48。键盘按下啥,先变成它的ASCII码。
【知识点·汉字编码三关】
- 🎓 输入码(拼音/五笔)→ 国标码/机内码(存储交换,两字节、每字节最高位为1以区别ASCII)→ 字模码(点阵字形,用于显示打印)。
- 🌱 打字时:你敲拼音(输入码)→机器存成内码→要显示时查字库画出点阵(字模码)。三种码各管一段。
【知识点·奇偶校验码】
- 🎓 在有效信息后加1位校验位,使”1”的个数为奇数(奇校验)或偶数(偶校验):C = x₀⊕x₁⊕…⊕xₙ₋₁。只能检奇数个错,不能纠错。
- 🌱 传数据怕出错,就多加一位”凑数位”,让1的总数保持单数或双数;收到后一数,单双变了就知道传错了(但不知道错在哪、也不止一位错时会漏判)。
2.2 定点加减运算(a+b 真正发生的地方)
【知识点·补码加减法(核心)】
- 🎓 补码加法:[x+y]补 = [x]补 + [y]补(连符号位一起加,模运算自动丢弃溢出进位)。补码减法:[x−y]补 = [x]补 + [−y]补。
- 🌱 这就是补码的全部意义——加减法都用一个加法器搞定,符号位也一起算,不用单独处理正负。我们的
a+b就是把 a、b 的补码直接相加。
例: x=+1001, y=−0101, 求 x+y (5位补码)
[x]补 = 0 1001
+ [y]补 = 1 1011
─────────────────
1 0 0100 → 最高位进位被丢弃(模运算) → 结果 0 0100 = +0100 = +4 ✓
【知识点·溢出判断(必考,溢出≠进位)】
- 🎓 两个同号数相加,结果符号相反即溢出。检测法:
- 双符号位法(变形补码):用两位符号位 Sf1Sf2,
00正常(正)、11正常(负)、01正溢、10负溢;溢出 V = Sf1 ⊕ Sf2。 - 单符号位法:V = 符号位进位 Cf ⊕ 最高数值位进位 C0。
- 双符号位法(变形补码):用两位符号位 Sf1Sf2,
- 🌱 溢出=结果超出了机器能表示的范围(俩正数加出个负数,俩负数加出个正数)。双符号位就是”用两个符号位看打架结果”,两个符号位不一样就是溢出。
例: x=+1100, y=+1000 (双符号位)
[x]补 = 00 1100
+ [y]补 = 00 1000
─────────────────
01 0100 两符号位 01 → 正溢出!(两正数加成了"负数")
🔑 超易错:进位 ≠ 溢出。无符号数看进位(Cf=1表示进位),有符号数看溢出(双符号位不等或Cf⊕C0=1)。
【知识点·一位全加器 FA(Full Adder,全加器——能同时接收两个加数和低位进位、输出本位和与进位的基本电路单元)】
- 🎓 FA 输入 Ai、Bi、低位进位 Ci,输出本位和 Si = Ai⊕Bi⊕Ci,进位 Ci+1 = AiBi + (Ai⊕Bi)Ci。n位行波进位加法器把n个FA串起来。
- 🌱 全加器就是”管一位加法、还要算给上一位的进位”的小电路;串成一排就能加多位数。做减法时把减数取反、最低位补1(求补)即可。
2.3 定点乘法运算
虽然 a+b 不做乘法,但课本要求掌握——挂靠在”如果程序里有 a*b 会怎样”。
【知识点·原码一位乘 / 阵列乘法器】
- 🎓 原码乘法:符号位单独异或决定,数值位做”部分积逐位累加+右移”;n位×n位积为2n位。硬件用阵列乘法器把部分积并行相加(流水式取代串行)。
- 🌱 跟你列竖式乘法一模一样:一位一位乘、错位相加;符号另算(同号正、异号负)。阵列乘法器就是把这堆加法用一片电路同时做完,快。
【知识点·带符号阵列乘法器(补码乘)】
- 🎓 采用”算前求补 → 乘法器 → 算后求补”:把操作数取绝对值相乘,再根据符号决定结果是否求补。
- 🌱 先把负号摘掉只乘绝对值,最后再按”同号正异号负”把符号和补码补回去。
例:x=+15, y=−13,|x|·|y|=1111×1101=11000011,符号 0⊕1=1(负)→ 结果 −195。
2.4 定点除法运算
【知识点·原码除法:恢复余数 vs 加减交替】
- 🎓 商符=被除数符⊕除数符;数值部分反复”上商、余数左移、加/减除数”。恢复余数法:余数为负要先加回除数再继续(步骤不定);加减交替法(不恢复余数法):余数为正→商1、下次减;余数为负→商0、下次加,步骤固定,机器常用。
- 🌱 长除法的机器版。“恢复余数”=减多了就再加回来(麻烦);“加减交替”=减多了不加回来,下一步改成加,反正最后能凑对(省事,所以机器都用它)。
加减交替法口诀:
余数为正 → 上商 1 → 下一步:余数左移后【减】除数
余数为负 → 上商 0 → 下一步:余数左移后【加】除数
共做 n 步求 n 位商;若最后一步余数为负,需补加一次恢复(不移位)
2.5 定点运算器的组成
【知识点·逻辑运算】
- 🎓 逻辑非(按位取反)、逻辑加(按位或)、逻辑乘(按位与)、逻辑异(按位异或),均按位独立运算、无进位。
- 🌱 这些是”一位管一位、互不进位”的运算,C语言里的
~ | & ^就是它们。
【知识点·ALU 与先行进位(74181/74182)】
- 🎓 多功能算术/逻辑单元 ALU 通过控制端 S0–S3、M 选择16种算术、16种逻辑运算;为提速用”先行进位(超前进位)“:Cn+4 = G + P·Cn(G进位产生、P进位传递),片内先行、片间可再用74182实现成组先行进位。
- 🌱 ALU 是运算器的”心脏”,能算能逻辑,靠几个开关选功能。普通加法器进位要一位一位往上传(慢,像多米诺骨牌),“先行进位”是提前把所有进位一次算出来(快)。
单/双/三总线运算器结构(数据在ALU和寄存器间怎么走)
单总线: 所有部件挂一条总线,一次只能传一个数,慢,控制简单
双总线: 两条总线,两个操作数可同时送入ALU
三总线: ALU两输入+一输出各一条,速度最快
2.6 浮点运算与浮点运算器
【知识点·浮点加减五步(必背流程)】
设 x = 2^Ex · Mx, y = 2^Ey · My
① 对阶 (0操作数检查后) ── 小阶向大阶看齐:阶小的尾数右移,阶码增大,直到 Ex=Ey
② 尾数加减 ────────────── 对齐后的尾数做补码加减
③ 规格化 ──────────────── 结果尾数最高有效位要有效:
右规:尾数右移1位、阶码+1(尾数溢出时)
左规:尾数左移1位、阶码−1(尾数最高位非有效时)
④ 舍入 ────────────────── 0舍1入 / 截尾 / 朝±∞舍入
⑤ 判溢出 ──────────────── 看阶码:阶码上溢→±∞;阶码下溢→当0处理
- 🎓 浮点加减必须先对阶再运算,原因是只有指数相同,尾数才能直接对位相加。
- 🌱 就像 3万 + 5千要先写成”3.0万 + 0.5万”才能加——先把数量级对齐,再加尾数,最后整理成规范写法、四舍五入、看会不会爆表。
🔑 易错:①对阶一定是”小阶向大阶”(小数右移会丢精度,但保住了大数);②左规可能要移多位,右规只移一位;③阶码用补码/移码判上下溢(双符号位 01上溢、10下溢)。
【知识点·浮点乘除】
- 🎓 x×y:阶码相加、尾数相乘;x÷y:阶码相减、尾数相除;最后规格化+舍入。
- 🌱 科学计数法乘法:指数相加、有效数字相乘((2×10³)(3×10²)=6×10⁵),除法反过来。
【知识点·流水线浮点运算器】
- 🎓 把浮点加分成”求阶差→对阶→相加→规格化”四段,每段一个部件、段间加锁存器,多个运算重叠进行(时间并行)。
- 🌱 像流水线洗车:一辆车在吹干时,下一辆已在打蜡——四个步骤同时各处理一个运算,吞吐量大增(详见第5章流水线)。
⭐ 本章在 a+b 故事里的位置
现在我们知道:a、b 在机器里以补码存着;a+b 由 ALU 用补码加法完成,做完还要判溢出。乘除、浮点是同一套思路的延伸。但还有个问题没解决:这些指令和 a、b,到底放在哪儿?CPU 取它们快不快? 这就是下一章——存储器。
🧪 费曼检验区(合上笔记,用自己的话说)
规则:合上笔记,试着说给完全不懂的人听。卡壳了就说明没真懂,回头重读。
📌 老师划重点(综合题必出)
- 综合题考补码运算、译码(除法不太会考)
- 选择题考 IEEE754 转换
📊 教材核心考点
- 什么是补码?为什么计算机用补码而不是原码?(提示:能说清”模”和”时钟”类比就过关)
- 原码、反码、补码、移码——四种码的转换关系是什么?移码和补码什么关系?
- 双符号位判断溢出的规则是什么?“溢出”和”进位”有什么区别?
- IEEE754单精度三个字段(S/E/M)分别是什么?偏移量为什么是127不是128?“隐藏的1”是怎么回事?
- 浮点数加减法的五个步骤是什么?为什么对阶要”小阶向大阶看齐”?
- 把 -12.625 转成 IEEE754 单精度,你能不看笔记完整做出来吗?
📝 章节小测
先动笔算完再看答案。本章是计算题最大富矿,综合题必出。
【题 1 · 计算 · 补码加减+溢出】 设机器字长 8 位(含 1 位符号位),x = +105,y = +45。用双符号位法计算 [x+y]补,判断是否溢出。
【题 2 · 计算 · IEEE754】 将十进制数 −12.625 转换为 IEEE754 单精度浮点数(写出 32 位二进制和对应的十六进制)。
【题 3 · 计算 · 浮点加法】 设 x = 2¹ × 0.1101,y = 2⁴ × (−0.1010)(阶码、尾数均用补码表示,阶码 4 位含 1 位符号位,尾数 8 位含 2 位符号位)。求 x + y,写出对阶、尾数加减、规格化、舍入的每一步。
【题 4 · 判断】 “两个补码相加,如果最高位产生了进位,就一定发生了溢出。” 对还是错?
【题 5 · 简答】 为什么补码能把减法变成加法?用 5 位 CPU 和 7 − 3 这个例子,写出具体的二进制运算过程。
参考答案(点击展开)
题 1:
- [x]补 = 00 1101001(双符号位,+105 = 01101001)
- [y]补 = 00 0101101(+45 = 00101101)
- 相加:00 1101001 + 00 0101101 = 01 0010110
- 双符号位 01 → 两位不同 → 正溢出。结果 10010110 若当无符号看是 150,超出 8 位有符号范围(−128~+127),确实溢出。
题 2:
- 12.625 = 1100.101₂ = 1.100101 × 2³
- S = 1(负数);e = 3 → E = 3 + 127 = 130 = 10000010
- M = 100101(去掉隐藏的 1.)后补零到 23 位:10010100000000000000000
- 32位:1 10000010 10010100000000000000000
- 十六进制:按4位一组分 → C14A0000
- 验证拆回:S=1, E=130, e=3, 1.100101×2³ = 1100.101 = 12.625, 加负号 = −12.625 ✓
题 3:(这道偏简答分析,写清每步即可)
- x 的阶 = 0001(+1),y 的阶 = 0100(+4);阶差 = 1−4 = −3
- ① 对阶:小阶向大阶,x 的尾数右移 3 位,阶码变 0100: x 尾数 00.1101 → 右移3位 → 00.0001(101 被移出,最后一个 1 用于舍入)
- ② 尾数加减:00.0001 + 11.0110(y 尾数 −0.1010 的补码 = 11.0110)= 11.0111
- ③ 规格化:11.0111 符号为负且非 11.0xxx 形式 → 已是规格化(负数补码规格化形式为 11.0xxx 或 10.xxx → 11.0111 满足)
- ④ 舍入:移出位 101 > 100,0舍1入 → 尾数末位 +1 → 11.1000
- 规格化检查:11.1000 = −0.1000,符号位 11 但最高有效位是 1 → 需左规1位 → 11.0000,阶码 0100−1=0011
- 结果:x + y ≈ 2³ × (−0.1000) = −(0.1)₂ × 2³ = −4
- (注:浮点题细节多,考试写清每步过程即可得分,具体舍入规则看题目约定)
题 4:错。进位 ≠ 溢出。例如 (−3) + (−5) = −8(8 位补码:11111101 + 11111011 = 1 11111000,最高位进位 = 1,但结果 −8 没溢出)。判溢出要看双符号位是否相同(或 Cf ⊕ C0),不能看最高位进位。
题 5:5 位机器的模 M = 2⁵ = 32。−3 的补码 = 32 − 3 = 29 = 11101。
00111 (7) + 11101 (−3 的补码 = 29) ───────── 100100 → 6 位,最高位溢出丢弃 → 00100 = 4 ✓硬件只做加法,“满 32 归零”自动丢掉进位,结果等于 7−3=4。减法通过”加上减数的补码”变成了纯加法,只需一个加法器 + 取反电路。
🎯 本章高频考点 & 易错坑
- 计算(本章核心):原/反/补/移码互换;补码加减+溢出判断;IEEE754 互转;浮点加减五步。
- 设计:阵列乘法器、先行进位 Cn+4 表达式、ALU。
- ⚠️ 坑:进位≠溢出;对阶是”小向大”;IEEE754 阶码偏移 + 隐藏位;加减交替法的加/减方向。