← 上一章:第1章 | 📖 目录 | 下一章:第3章 →


第 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
01−0=11
11−1=00

两列完全一致。所以 “全 1 减一个数” 在硬件上根本不需要减法器——只要给每一位接一个”非门”(NOT,单晶体管就能造,已知最便宜的电路元件)就行。这就是补码”取反加 1”在硬件层面真正廉价的原因。

这就是教材里那句”反码末位加 1 得补码”的真正来源——它不是凭空规定的口诀,而是 “M − |x|” 这个数学事实的硬件友好实现:先全 1 减一下(已证等价于按位取反,只用非门),再 +1(也简单)。

🔑 看到这你应该悟了:补码这套设计是两层抽象:

  1. 数学层面:负数 ≡ “模 − 绝对值” → 减法变加法
  2. 硬件实现层面:模 − 绝对值 = 取反 + 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。
  • 🌱 溢出=结果超出了机器能表示的范围(俩正数加出个负数,俩负数加出个正数)。双符号位就是”用两个符号位看打架结果”,两个符号位不一样就是溢出。
例: 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 取它们快不快? 这就是下一章——存储器。


📝 章节小测

先动笔算完再看答案。本章是计算题最大富矿,综合题必出。

【题 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 这个例子,写出具体的二进制运算过程。

🎯 本章高频考点 & 易错坑

  • 计算(本章核心):原/反/补/移码互换;补码加减+溢出判断;IEEE754 互转;浮点加减五步。
  • 设计:阵列乘法器、先行进位 Cn+4 表达式、ALU。
  • ⚠️ 坑:进位≠溢出;对阶是”小向大”;IEEE754 阶码偏移 + 隐藏位;加减交替法的加/减方向。

← 上一章:第1章 | 📖 目录 | 下一章:第3章 →