00 · 入门
电脑怎么算数:从开关到加法器(进阶)
本篇你将学到
- 逻辑门:用开关和灯就能做“判断”
- 怎么用几个门搭出会做加法的电路
- 电脑怎么只靠加法和“挪位置”算出减、乘、除
上一篇说过,电脑里的数字就是一排开关(0 和 1)。这一篇看看,开关是怎么“算”出 5 + 6 的。干这活的,是 CPU 里叫算术逻辑单元(ALU)的部分,意思就是“专门做算术和简单判断的小车间”[4](CPU 见 00-03 的 CPU 小节)。
逻辑门:开关和灯
想象一盏灯,前面接着开关。按不同方式接线,就得到几种最基本的“门”[5]:
| 门 | 什么时候灯亮(输出 1) | 生活里像 |
|---|---|---|
| 与(AND) | 两个开关都是 1 | 两个开关串在一根线上 |
| 或(OR) | 至少一个是 1 | 两个开关并排接 |
| 非(NOT) | 开关是 0 时 | 反着来的开关 |
| 异或(XOR) | 两个开关不一样时 | 楼梯上下两个开关控制同一盏灯 |
真正的芯片里,“开关”是几十亿个极小的晶体管,但道理就是这几种门[5]。
用门搭一个加法器
一位加一位只有四种情况:0+0=0,0+1=1,1+0=1,1+1=10(写 0,进 1)。仔细看:
- “这一位写几”:两个数不一样时是 1 → 正好是异或门;
- “要不要进位”:两个数都是 1 才进位 → 正好是与门。
但多位数相加时,每一位除了 A、B,还要加上右边送来的进位,一共三个数。把两个半加器接起来(先算 A+B,再加进位),两边任一边进位就向左进 1(用一个或门),就得到全加器[2][6]。
把 4 个全加器排成一排,每个的进位输出接到左边那个的进位输入,就是一个 4 位加法器。进位像接力棒一样从右往左一位一位传,所以叫“行波进位”[1][2]。电脑里的加法器原理一样,只是有 32 位、64 位那么宽,还用了更快的进位方法[2]。
自己点一点:先在“单个门”里认识四种门,再看半加器、全加器,最后在 4 位加法器里试试 5 + 3、9 + 8(会溢出),以及勾上“做减法”算 5 − 3、3 − 5。
绿色粗线 = 1(有电),灰色细线 = 0(没电);黄灯亮 = 1。电路已简化,只为说明原理。
加减乘除
先在纸上算:满 2 进 1
二进制加法和小学的竖式加法一模一样,从最右边一位开始加,只是十进制“满 10 进 1”,二进制是满 2 进 1[1]。所以只有四种情况要记:0+0=0,0+1=1,1+0=1,1+1=10(写 0,向左进 1)。
比如 5 + 6(用 4 位来写):
进位 1
5 = 0101
+ 6 = 0110
───────────
11 = 1011
从右往左:1+0=1;0+1=1;1+1=10,写 0 进 1;0+0 再加进上来的 1,得 1。结果 1011 就是 8+2+1=11。
减法:加上一个“负数”
上面的加法器只会加,所以电脑不另外造减法器,而是把“减去 6”变成“加上负 6”[2]。那负数怎么写?有个很巧的办法,叫补码,做法就两步:把每一位 0 变 1、1 变 0,再加 1[2][3]。
用 4 位举例算 7 − 6:6 是 0110,翻转得 1001,再加 1 得 1010,这就是“负 6”。然后 7 + (负 6):
0111 (7)
+ 1010 (负 6)
─────────
10001
结果有 5 位,但我们只有 4 个格子,最左边多出来的 1 直接扔掉,剩下 0001,就是 1。答案对了!
在电路里,“翻转”就是让 B 的每一位过一个非门,“再加 1”就是把最右边那个全加器的进位输入设成 1——还是同一个加法器[2]。上面模拟里勾上“做减法”就能看到。
可以把它想象成汽车的里程表:4 位的表只能显示 0000 到 1111,再往上加就“转满一圈”回到 0000。在这样的表上,“往前走 10 格”和“往回退 6 格”停在同一个位置,所以加上 1010 就等于减去 6。
乘法:加法 + 挪位置
在十进制里,一个数后面添个 0 就变成 10 倍:25 → 250。二进制也一样,只不过后面添个 0(也就是整体往左挪一格)是变成 2 倍:3 是 11,往左挪一格变成 110,就是 6[1]。
乘法就是用这个办法:看乘数的每一位,是 1 就把被乘数(挪好位置后)加进来,是 0 就跳过,最后全部加起来[1]。比如 5 × 3,3 是 11:5(101)加上“往左挪一格的 5”(1010),101 + 1010 = 1111,就是 15。
除法:反复试着减
13 块糖,每人分 3 块,能分给几个人?一次拿走 3 块:13 → 10 → 7 → 4 → 1,拿了 4 次,剩 1 块。所以 13 ÷ 3 = 4 余 1——除法就是反复减,数减了几次。
数字大了一次次减太慢,所以像小学长除法那样,从左边一位一位算。二进制每位只能是 0 或 1,所以每步只问一句:够减就减掉、商写 1;不够就商写 0,再拿下一位[1]。
13 ÷ 3(1101 ÷ 11):
| 第几步 | 拿下一位后,手里的数 | 够不够减 11(3) | 商写 | 剩下 |
|---|---|---|---|---|
| 1 | 1(1) | 不够 | 0 | 1(1) |
| 2 | 11(3) | 够 | 1 | 0(0) |
| 3 | 0(0) | 不够 | 0 | 0(0) |
| 4 | 1(1) | 不够 | 0 | 1(1) |
每步把上一步“剩下”的数后面接上新拿下的一位。商从上往下读 0100 就是 4,剩 1,和分糖一样。除以 2 更简单:整体往右挪一格,挪出去的那位就是余数[1]。
4 个开关只能装到 15,数字大了就用下面的计算器:电路一样,只是位数多一些。试试“5 + 6”,再切换成减法试试“7 − 6”和“3 − 5”,乘法试试“5 × 3”,除法试试“13 ÷ 3”:
小结
- 逻辑门就是开关和灯:与(都亮才亮)、或(有一个就亮)、非(反着来)、异或(不一样才亮)。
- 异或 + 与 = 半加器;两个半加器 + 或 = 全加器;一排全加器 = 多位加法器。
- 减法 = 翻转再加 1,用的还是同一个加法器;乘法 = 加法 + 往左挪;除法 = 反复试着减。
- 把这些电路组合起来、再加上“选哪种运算”的开关,就是 CPU 里的 ALU[4][6]。
下一篇是术语表,把这几篇里出现的词集中整理一遍,忘了随时回来查。
参考资料
- [1]CIS 371 Computer Organization and Design · Unit 4: Arithmetic · University of Pennsylvania (Milo Martin)
https://acg.cis.upenn.edu/milom/cis371-Spring11/lectures/04_arith.pdf - [2]6.111 Lecture 8: Arithmetic Circuits & Multipliers · MIT
https://web.mit.edu/6.111/www/f2016/handouts/L08.pdf - [3]Two's Complement · Thomas Finley, Cornell University
https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html - [4]What is a Central Processing Unit? · Arm
https://www.arm.com/glossary/cpu - [5]Project 1: Boolean Logic · Nand2Tetris (Nisan & Schocken)
https://www.nand2tetris.org/project01 - [6]Project 2: Boolean Arithmetic · Nand2Tetris (Nisan & Schocken)
https://www.nand2tetris.org/project02