JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

用 0 和 1 思考

電腦做的一切——音樂、數學、影片,乃至你正在讀的這句話——都只用兩個值:1 和 0。本文帶你看清,這麼小的「詞彙表」是怎麼變成會思考的機器的。

類比與數位

想想檯燈上的調光旋鈕。你慢慢轉動它,燈光就在所有亮度之間平滑滑動——昏暗、稍亮、再亮一點——中間沒有任何階梯。這就是類比訊號:它的取值可以是連續範圍裡的*任意*一個數,就像你說話的音量,或者海面上浪頭的高度。

數位訊號則故意把這些中間的豐富層次全部丟掉。它不允許無窮多的灰階,只允許兩個電平——叫它們,或者10。它不像調光旋鈕,更像一個普通的開關燈:燈泡要麼亮、要麼滅,中間什麼都沒有。

為什麼要放棄這些細節?因為雜訊。導線會沾上雜散的電擾動,就像麥克風會收到背景的「嘶嘶」聲一樣,所以承載你訊號的那個電壓總是有點被抹花。對類比值來說,每一點抹花都會改變結果。可一旦規則只是「夠高就算 1,夠低就算 0」,中間還留著一段寬裕的間隔,那麼幾個百分點的抹花就完全無所謂了——接收方讀到的還是乾乾淨淨的 1 或 0。把世界壓進兩個清清楚楚的選項裡,正是數位之所以穩固的原因。

邏輯閘

一旦世界只剩 1 和 0,你就需要一些小機器來*拿它們做點事*。這些小機器就是邏輯閘,每一個都遵守一條死板而簡單的規則:輸入一兩個位元,輸出一個位元。你最先會遇到的三種是 AND(及閘)、OR(或閘)和 NOT(反閘)。

它們的行為和這些英文詞的字面意思一樣。AND(及)閘只在*兩個*輸入都是 1 時才輸出 1——就像一扇得兩個人同時轉動鑰匙才打開的門:0 AND 0 得 0,1 AND 0 得 0,只有 1 AND 1 才得 1。OR(或)閘只要*任一*輸入是 1 就輸出 1,像一盞接在兩個開關上的燈——0 OR 0 得 0,而 1 OR 0 就得 1。NOT(反)閘是個孤獨的唱反調者:餵它 1,它吐出 0;餵它 0,它吐出 1。

那這些閘究竟是用什麼*做*的呢?主要是電晶體——微小到沒有任何活動部件的電開關,每一個都由一根控制線上的電壓來撥開或撥關。把幾個電晶體按一種方式接起來,它們就服從 AND 規則;換一種接法,你就得到 OR 或 NOT。一塊現代晶片裡塞著數十億個這樣的開關,於是它就有數十億個閘可供調度。

布林真值

接下來是把這一切串起來的那個不動聲色的妙處。早在電腦出現之前,有位叫喬治·布爾的數學家就琢磨出了的代數——一種像算數字那樣去*運算*陳述句的方法。我們今天管它叫布林代數,它的整個宇宙裡只有兩個值。如果讓代表 1、代表 0,那麼布爾的真假數學和你那些閘的 1/0 行為,根本就是同一件事換了身衣裳。

這一對應,正是從電流通往思考的橋樑。正因為布林代數是數學裡實打實的一個分支,任何人都能拿張紙、一支筆坐下來,*證明*一團亂麻似的閘到底會幹什麼——根本不用動烙鐵。而且數學家很久以前就證明了:AND、OR、NOT 這三個不起眼的運算,足以表達你能想像到的任何真假規則,無論它多麼繁複。

把足夠多的閘疊起來,這些簡單的選擇就開始累加——而且是字面意義上的累加。這就是它的核心:一條把兩個單一位元相加、並回報結果以及是否「進位」的規則。把它當成純粹的布林邏輯來讀,你會發現整件事不過是 AND、OR、NOT 的偽裝。

sum   = (A OR B) AND NOT (A AND B)   // 1 when exactly one input is 1
carry = A AND B                      // 1 only when both inputs are 1

// 0 + 0  ->  sum 0, carry 0
// 1 + 0  ->  sum 1, carry 0
// 0 + 1  ->  sum 1, carry 0
// 1 + 1  ->  sum 0, carry 1   (i.e. binary 10, "two")
一個一位元加法器,完全用 AND / OR / NOT 寫成。把許多個這樣的加法器串起來,你就能把任意兩個數相加——還是那些閘,只是不斷重複。

記憶:正反器與時脈

閘擅長*反應*,卻毫無記憶——你一改輸入,輸出立刻就忘了它剛才是什麼。一台什麼都記不住的電腦毫無用處,所以我們需要一種電路,能攥住一個位元,直到被告知改變為止。這種電路就是正反器

正反器是幾個閘巧妙地首尾相接、互相回饋構成的一個環路,於是它們把自己的輸出撐住、穩穩地保持——你可以想像成一個撥到哪兒就停在哪兒的開關。每個正反器恰好記住一個位元:一個 1 或一個 0。把八個排成一行,你就能存下一個數;把數十億個排起來,你就擁有了程式賴以生存的記憶體。

可如果上百萬個正反器各自想更新就更新,結果就會一片混亂——到處都是半成品的數字撞在一起。所以晶片裡有位指揮:時脈,一個每秒在高低之間翻轉成百萬乃至上億次的電壓,滴答、滴答。每個正反器都被規定:在滴答的那一下去看自己的輸入並更新。兩次滴答之間,大家都紋絲不動,閘則悄悄把各自的答案穩定下來。

  1. 滴答。 每個正反器把此刻輸入上的那個位元拍個快照,鎖存下來。
  2. 滴答之間。 這些被攥住的位元流過各個閘,閘算出下一輪結果——一個和、一次比較、下一條指令。
  3. 下一次滴答。 正反器捕獲這些新鮮的結果,整台機器步調一致地一起向前邁一步。