qinghuan
← 回到知识探索

计算机趣闻 / 趣味知识

只有开和关,怎样算出与、或、非?

把开关摆成不同的通路,再用四行输入检查它是否做对了。

展开本文目录
  1. 先动手看看
  2. 先约定标签,再讨论电路
  3. 一条路都要通,还是有一条通就行
  4. 非,是让结果反过来
  5. 把四种情况都跑一遍
  6. 记住这三点
  7. 别把例子用过头
  8. 自己试一小步
  9. 查原始资料
  10. 找一份资料继续练
开始前,会这些就够了
  • 认识 0 和 1
  • 运行代码需 Node.js 20 或更新版本

假设我们做一个桌面提示灯:两个人都按下按钮才亮,或者任意一个人按下就亮。按钮仍然只有按下与松开两种状态,改变连接方式,灯却能遵守不同规则。计算可以先从这样的选择开始。

拨两个开关,看四种规则

勾选表示输入为 1,不勾选表示 0。先预测“两个都开”时,与、或、与非各会输出什么。

输入开关
非 a
1

把 a 反过来

a 与 b
0

两者都为 1

a 或 b
0

至少一个为 1

a 与非 b
1

把“与”的结果反过来

全部四种输入;“当前”标出你选的这一行
状态ab非 a与或与非
当前001001
—011011
—100011
—110110

这里的 0 和 1 是逻辑标签,不是测得的电压。“或”包含两个输入同时为 1 的情况。

先约定标签,再讨论电路

在这个假想模型里,输入为 1 表示条件成立,为 0 表示不成立;灯亮记为输出 1,灯灭记为 0。两个输入只有四种组合:00、01、10、11。把每种组合对应的结果都写下来,便得到真值表,也就是完整的输入输出清单。

这里的数字是标签,不是承诺所有芯片的 1 都等于一伏、0 都等于零伏。实际器件会规定能可靠识别的电压范围,信号变化也需要时间。下面先研究条件关系,暂不模拟电压、发热或电流大小。

同一个输入也可以代表门是否关好、任务是否完成,或用户有没有勾选选项。门电路本身不认识这些含义,只遵守我们约定的组合规则。先写清每个标签代表什么,才知道输出能不能解决原来的问题。

一条路都要通,还是有一条通就行

把两个理想开关放在同一条路上,只有两处都闭合,通路才完整。这对应“与”:两个输入都是 1,输出才是 1。桌面灯若要求两人共同确认,就可以用这个规则;仅有一个人按下仍然不够。

再让两个开关分别控制两条并排的路,只要有一条通,灯就能亮。这对应“或”。两个人同时按下也满足要求,不能误读成“只能二选一”。若要表达恰好一个条件成立,则需要另一种规则:异或。

非,是让结果反过来

“非”只有一个输入:原来是 0 就输出 1,原来是 1 就输出 0。可以想象一个受输入控制的常闭开关:没有触发时通,触发后断。它是帮助理解反转的模型;普通按钮断开后不会凭空生成一个有效的反向电信号。

还可以用同一种零件拼出这三条规则。NAND 叫作“与非”,只在两个输入同为 1 时输出 0,其余都输出 1。把它的两个输入接到同一个信号,就得到“非”;把与非结果再反转,就得到“与”。

“或”也能这样组合:先分别反转两个输入,再把结果送进 NAND。只要原来有一个输入是 1,反转后就至少有一个 0,NAND 便输出 1;原来两者都是 0 时,结果才是 0。

把四种情况都跑一遍

代码先定义一个只接受 0、1 的 NAND,再组合出三个函数。最后两列分别是与、或的结果。先画出自己的四行表,尤其预测输入 11 的那一行,再运行比较。函数嵌套表示前一个结果继续作为下一个输入。

运行结果相同,说明这几种写法在所列输入上有相同的逻辑行为。因为两位输入的四种情况都列齐了,这里不是只碰巧通过几个例子。它仍不能证明真实电路的速度或电气可靠性;教学游戏和代码也不等于芯片的物理模拟。

小实验 · javascript
function nand(a, b) {
  if (![a, b].every(x => x === 0 || x === 1)) {
    throw new TypeError("inputs must be 0 or 1");
  }
  return 1 - (a & b);
}
const not = a => nand(a, a);
const and = (a, b) => not(nand(a, b));
const or = (a, b) => nand(not(a), not(b));

console.log("a b NOT(a) AND OR");
for (const a of [0, 1]) {
  for (const b of [0, 1]) {
    console.log(a, b, not(a), and(a, b), or(a, b));
  }
}

怎样运行:保存为 gates.js,在终端运行 node gates.js。使用 Node.js 20 或更新版本,无需安装依赖。

运行后对照结果
a b NOT(a) AND OR
0 0 1 0 0
0 1 1 0 1
1 0 0 0 1
1 1 0 1 1

记住这三点

  • 与要求全部成立,或允许同时成立。
  • 非会反转一个输入,NAND 可以组合出这三种规则。
  • 真值表检查逻辑关系,不测量真实电路的物理表现。

别把例子用过头

  • 不要把逻辑标签 0、1 当成所有芯片统一的电压值。
  • 并联开关只是通路类比,不是完整芯片接线图。

自己试一小步

设计一个“已授权,并且没有暂停”的提示灯规则。

  1. 用 a 表示已授权、b 表示暂停。
  2. 先写四行结果,再组合本文函数。
  3. 运行所有输入并与预测比较。

做到这些,就算完成

  • 四种输入齐全。
  • 说明每个输入的含义。
  • 不把逻辑模拟称为真实接线测试。

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。