📄 一句话概括

计算机不会算数,它只会开关。 加法是用几个开关(逻辑门)搭出来的电路:异或门算本位,与门算进位。 减法也不是单独的电路 —— 把减数取补码,减法就变成加法,一套电路干两件事。 [!tip] 承接前两篇 - [[01 二进制原理入门]]:0 和 1 是什么 - [[02 信息的数字化表示]]:真实世界怎么变成 0 和 1 - 本篇:这些 0 和 1 进去之后,电路怎么把它们算出来


1. 先搞懂一个前提:电脑没有"数字",只有"电压"

你以为电脑里的 实际在电路里的
数字 1 一根导线上的高电压(如 3.3V)
数字 0 一根导线上的低电压(约 0V)
加法 几个开关按规则互相控制

逻辑门(Logic Gate) 就是这样一个"看输入电压、决定输出电压"的小电路。

📝 关键认知

逻辑门没有智能。它只是一个物理器件: 输入端电压满足某个条件,输出端就给出对应电压。 所谓的"计算",就是电流在几百个门里按固定路线跑一遍的结果。


2. 四个基本逻辑门

门 口诀 真值表(A B → Y)
与门 AND 全 1 才出 1 0 0→0 0 1→0 1 1→1
或门 OR 有 1 就出 1 0 0→0 0 1→1 1 1→1
非门 NOT 反过来 0→1 1→0
异或门 XOR 不一样才出 1 0 0→0 0 1→1 1 1→0

✅ 为什么异或门是主角?

把它的真值表和我们小学的加法对比一下:

算式 本位结果 异或门输出
0 + 0 = 0 0 0 ✅
0 + 1 = 1 1 1 ✅
1 + 0 = 1 1 1 ✅
1 + 1 = 10 本位 0 0 ✅

完全一致。 异或门天生就是"加法本位"的电路。 [!note] 用一句话描述异或门 "两个输入不一样,输出 1;两个输入一样,输出 0。" 这个动作在数学上叫"模 2 加"(不进位加法)。


3. 半加器:两个门拼出"1 位加法"

现在解决进位问题。1 + 1 时本位是 0,但要多出一个 1 送给高一位。这个"多出来的 1"什么时候出现?

只有当 A 和 B 都是 1 的时候才出现 —— 这正是与门。

算式 本位(异或门) 进位(与门)
0 + 0 0 0
0 + 1 1 0
1 + 0 1 0
1 + 1 0 1 ✅

异或门 + 与门 = 半加器(Half Adder)

⚠️ 半加器的缺陷

它只有两个输入 A、B。可是做 8 位加法时,每一位还要接收来自低位的进位。 半加器没有这个入口 —— 所以它只能当"半成品",名字也由此而来。


4. 全加器:真正能用的一位加法器

给半加器补上一个进位输入口,就是全加器(Full Adder),输入变成三个:A、B、Cin(低位进位)。

电路怎么搭

本位 S   = A ⊕ B ⊕ Cin        (两个异或门串联)
进位 Cout = A×B 或 (A⊕B)×Cin   (两个与门 + 一个或门合并)

💡 怎么理解 Cout 这条式子

什么时候要往上进位?两种情况: 1. A 和 B 都是 1(A×B) 2. A、B 里有一个是 1,同时低位也送来了进位((A⊕B)×Cin)

任一种发生,就该进位 —— 所以最后用或门把两路合并。

完整真值表(8 种情况,只有 8 行)

A B Cin → Cout S 含义
0 0 0 0 0 0+0+0 = 0
0 0 1 0 1 0+0+1 = 1
0 1 0 0 1 0+1+0 = 1
0 1 1 1 0 0+1+1 = 2
1 0 0 0 1 1+0+0 = 1
1 0 1 1 0 1+0+1 = 2
1 1 0 1 0 1+1+0 = 2
1 1 1 1 1 1+1+1 = 3

📌 验算第 4 行

A=0, B=1, Cin=1 → 0+1+1 = 2 → 二进制 10 → Cout=1, S=0 ✅ 注意看:Cout 和 S 拼起来正好是两倍的 S 位的权。这说明电路算得没错。


5. 串起来算多位:行波进位加法器

一位不够用。要算 8 位、32 位,就把全加器并排串起来:

    [FA bit7] ← [FA bit6] ← ... ← [FA bit1] ← [FA bit0]
        ↑            ↑                  ↑          ↑
      进/出        进/出             进/出      Cin = 0

实例:算 5 + 3

      0 0 0 0 0 1 0 1     ← 5
    + 0 0 0 0 0 0 1 1     ← 3
    ─────────────────
      0 0 0 0 1 0 0 0     ← 8
                 ↑
            bit1 上 1+1 产生进位,传给 bit2

⚠️ 行波进位的缺点:慢

最高位的结果,必须等进位从最低位一路"爬"上来才知道。 32 位加法,最坏情况要等 32 个门依次翻转。 现代 CPU 用超前进位(Carry Look-ahead) 优化:直接由 A、B 一次性算出各级进位,不再排队等 —— 这就是现在一秒钟能算几十亿次加法的原因。 [!success] 乘法怎么办? 乘法就是加法的重复。 5 × 3 = 5 + 5 + 5。 CPU 用"移位 + 加法"实现:把乘数拆成 2 的幂次组合,每次左移一位(相当于 ×2)再决定加不加。 所以 CPU 里可以没有乘法器,但一定有加法器。


6. 减法:不用新电路,取个补码就行

这是整个设计里最漂亮的一招。

为什么要用补码?

如果给减法单独造一套电路,那 CPU 里就要有加法器 + 减法器 + …… 能不能让减法蹭加法器的车?

关键:如果能找到 −3 的一个二进制写法,让 7 + 它 的结果正好是 4,那就成了。

补码的求法:按位取反,再加 1

以 8 位、求 −3 为例:

3        = 0 0 0 0 0 0 1 1
按位取反  = 1 1 1 1 1 1 0 0
       +1
       ───────────────────
−3 的补码 = 1 1 1 1 1 1 0 1

用加法器验证:7 + (−3)

      0 0 0 0 0 1 1 1     (7)
    + 1 1 1 1 1 1 0 1     (−3 的补码)
    ───────────────────
    1 0 0 0 0 0 1 0 0     ← 多出第 9 位

把最高位溢出的 1 直接丢弃 → 剩下 00000100 = 4 ✅

📝 为什么丢掉就对了?

因为 8 位电路"装不下"第 9 位,溢出部分自动消失。 这是补码设计的精妙之处:溢出的丢弃不是错误,而是设计好的机制。 换句话说,"减 3"和"加 245"(11111101 的十进制值)在 8 位电路里是同一件事。

减法秒变加法的操作

要算 实际让加法器算
A − B A + (−B 的补码)

所以一个 8 位加法器,只要在 B 的输入端加一排非门(把 B 取反)再让 Cin = 1(完成"+1"),同一套电路立刻能算减法。

📝 这就是为什么 8 位二进制的范围是 −128 ~ 127

一半的数分给负数(最高位当符号位),所以正数只剩 0~127。


7. 一图总结:从电压到加法

电压高低            →  逻辑门(0/1 的规则)      →  一位全加器        →  多位加法器      →  减法/乘法
高=1 低=0              与门·或门·非门·异或门         异或算本位            串联 + 进位          补码 / 移位
                                                     与门算进位
层级 做什么 关键点
电压 表示 0 和 1 只有两档,抗干扰
逻辑门 0/1 的运算规则 无智能,纯物理开关
全加器 一位加法 异或管本位,与门管进位
多位加法器 多位加法 进位逐级传递(行波)
加减乘 全都归到加法 补码 + 移位

📝 提炼一句话

计算机的"计算能力",本质上是从"开关"里长出来的。 没有魔法,只有一层层搭起来的规则。


8. 常见误区自查

⚠️ 别踩这些坑
  1. "CPU 会算数" —— CPU 不会,它只会让电流穿过一堆门电路。
  2. "减法需要单独的电路" —— 不需要,取补码后走加法器,溢出丢弃即可。
  3. "溢出丢弃是 bug" —— 是设计。正因为丢弃,A + (−B 补码) 才能等于 A − B。
  4. "乘法是专门的乘法电路" —— 本质是移位 + 重复相加。
  5. "半加器和全加器只是名字不同" —— 差一个进位入口,全加器才能串联成多位。
  6. "进位是瞬间传完的" —— 行波进位要排队传,这是老式加法器的主要瓶颈。


9. 自测题(先自己算,再点开答案)

❓ - Q1. 为什么 1 + 1 的本位是 0?

因为本位由异或门决定,而"两个输入一样时异或门输出 0"。 1+1=10,本位上确实应该写 0,那个 1 交给进位。 [!question]- Q2. 进位 Cout 什么时候是 1? 两种情况:A 和 B 都是 1;或者 A、B 中有一个是 1 且低位送来了进位。 对应公式 Cout = A×B 或 (A⊕B)×Cin。 [!question]- Q3. 用 8 位补码算 10 − 4,写出过程。 −4 的补码:00000100 → 取反 11111011 → 加 1 → 11111100 10 = 00001010 00001010 + 11111100 = 1 00000110 丢弃溢出的最高位 → 00000110 = 6 ✅ [!question]- Q4. 8 位有符号整数能表示的范围是多少?为什么? −128 ~ 127。 最高位拿来当符号位,剩下 7 位表示大小;正数占 0~127,负数占 −128~−1。 [!question]- Q5. 为什么 CPU 里不需要"减法器"? 因为 A − B 可以改写成 A + (−B 的补码), 用同一个加法器配合"取反 + Cin=1"就能完成,省掉一整套电路。


10. 下一步学什么


相关笔记