La logica digitale degli zeri e degli uno
Chiudiamo il modulo sulla radiotecnica con le orecchie ancora piene di onde, avendo imparato a far viaggiare un messaggio lungo cavi, antenne e aria libera, e ripartiamo da quel segnale viaggiatore, perché il gradino che saliamo è il più delicato del percorso. Nei moduli precedenti il segnale era analogico, cioè una tensione libera di assumere infiniti valori, una curva morbida e continua, e questa grazia ha un prezzo, dato che ogni copia di un segnale analogico è approssimata come una fotocopia fatta a mano, nella quale si aggiunge un poco di rumore qua e una macchia di là, e dopo poche copie il disegno si sforma irriconoscibile.
Per liberarsi da questa deriva gli ingegneri hanno deciso di lavorare lontano dalla continuità, restringendo il segnale a pochi livelli netti, tipicamente due, e questa scelta ha un nome, ed è digitale, dal termine inglese digit, cifra. In un circuito digitale contano soltanto due zone di tensione, una bassa intorno allo zero volt per lo zero e una alta intorno ai cinque volt per l'uno, e le tensioni di mezzo sono bandite. Il punto geniale è la soglia, perché ogni porta legge il suo ingresso con un confine preciso, interpreta ogni tensione della zona bassa come uno zero perfetto e ogni tensione della zona alta come un uno perfetto, e poi riscrive il valore in uscita esattamente nella zona che gli compete, così un segnale che entra stanco ne esce rigenerato, e siccome ogni stadio rigenera possiamo concatenare milioni di porte senza accumulare errori.
Per usare con disinvoltura lo strumento dobbiamo prima imparare a contare con sole due cifre, e il
trucco sta nel peso posizionale, la stessa idea per cui nelle cifre decimali il due di ventitré vale
venti per il semplice fatto di trovarsi in seconda posizione contando da destra. In binario ogni
posizione vale il doppio di quella alla sua destra, partendo da uno, e così le posizioni valgono uno,
due, quattro, otto, sedici e via di questo passo, come i pesi di una bilancia antica che raddoppiano a
ogni gancio. Per convertire il numero tredici scriviamo i pesi finché non li superiamo, uno, due,
quattro, otto e sedici, poi chiediamoci a ognuno se ci sta dentro il resto, e il sedici non ci sta
per niente, l'otto ci sta e restano cinque, il quattro ci sta e resta uno, il due non ci entrerebbe, e
l'uno ci sta esatto, ottenendo la combinazione uno uno zero uno, che si scrive 1101 e si
legge un bit alla volta, e questo gioco di sottrazioni successive rende la conversione accessibile a
chiunque sappia contare il resto di una divisione.
Quando le file di bit si allungano gli uomini inventano scorciatoie, e la più diffusa raggruppa i
bit a quattro a quattro, in pezzi chiamati nibble, parola inglese che suggerisce un boccone
piccolo, ognuno dei quali copre sedici combinazioni, esattamente quante ne servono a una cifra
esadecimale che conta da zero a quindici usando le dieci cifre e poi le prime sei lettere dell'alfabeto,
così la stringa 1101 diventa D e la stringa 10100111 diventa A7. Torna qui
il byte, il gruppo di otto bit capace di rappresentare duecentocinquantasei valori diversi, da
zero a duecentocinquantacinque, quantità che basta per codificare una lettera o una cifra, e i gruppi
più lunghi prendono il nome di parole, con le macchine che hanno storicamente parlato parole da otto,
sedici, trentadue e sessantaquattro bit. I multipli salgono la scala con nomi che nascono dalle
potenze di due, perché un kilobyte vale milleventiquattro byte anziché mille, essendo due alla decima,
e megabyte e gigabyte proseguono la scala alla ventesima e alla trentesima potenza.
Per ragionare con metodo su questi zeri e questi uno ci serve una matematica nuova, inventata dal matematico inglese dell'Ottocento George Boole, e per questo chiamata algebra di Boole, un gioco di condizioni con variabili che valgono soltanto zero oppure uno, nel quale le operazioni fondamentali sono proprio quelle che tra poco incontreremo nelle porte AND, OR e NOT. Le identità di questo gioco si presentano a coppie, ognuna con la sua gemella che scambia AND con OR e zero con uno, come le due facce di una medaglia. Il primo paio racconta gli elementi neutri, cioè i compagni che lasciano tutto come lo trovano, perché una variabile qualsiasi unita in OR con lo zero resta invariata, così come lo stesso valore legato in AND con l'uno resta identico a se stesso. Il secondo paio è la dominanza, dove il numero più forte schiaccia il compagno, visto che una OR con l'uno produce sempre uno e una AND con lo zero produce sempre zero, un po' come al gioco dei dadi dove la mano che contiene il totale vince qualunque cosa faccia l'avversario. C'è poi la doppia negazione, la più intuitiva di tutte, perché rovesciare due volte di fila riporta il valore al punto di partenza, come dire due volte di seguito il contrario di una frase.
Le leggi seguenti somigliano alle regole dell'aritmetica ordinaria ma vanno maneggiate con rispetto, perché a volte regalano sorprese. La proprietà commutativa dice che scambiare l'ordine degli ingressi lascia invariato il risultato, la associativa promette che il modo di raggruppare tre variabili non cambia il valore finale, e la distributiva mostra come una variabile possa moltiplicare una somma o, nella forma gemella, come una somma possa distribuirsi su un prodotto. La legge di assorbimento è quella che più strega chi arriva dalla scuola, dato che una variabile unita in OR a una AND che la contiene resta semplicemente se stessa, come se il secondo pezzo venisse inghiottito dal primo. Infine arriva la legge di De Morgan, la più feconda di tutte, che spiega come negare una AND produca la OR delle negazioni e come negare una OR produca la AND delle negazioni, un risultato verificabile riga per riga con le tabelle di verità e per niente ovvio a intuito. Questa legge ha una conseguenza pratica che fa risparmiare soldi veri ai progettisti, perché un circuito che debba spegnere una spia quando due segnali sono entrambi presenti si può riscrivere come una OR con gli ingressi rovesciati, sostituendo porte costose con porte più semplici e dimezzando di tanto in tanto il numero di transistor.
Le operazioni di questa algebra vengono realizzate da dispositivi chiamati porte logiche (gate in inglese), e la più semplice di tutte è la porta NOT, detta anche invertitore, che rovescia ciò che riceve, emettendo uno quando il suo ingresso vale zero e zero quando vale uno. Il modo più comodo per descrivere una porta è la tabella di verità, una tabellina che accosta ogni combinazione degli ingressi al valore di uscita, e per la NOT è così piccola che la raccontiamo dentro una frase. Il suo simbolo è un triangolo con un cerchietto attaccato all'uscita, e lo schema che trovi qui sotto lo mostra.
La seconda porta si chiama porta AND e ragiona come due serrature una dietro l'altra sulla stessa porta di un castello, perché la sua uscita vale uno soltanto quando tutti i suoi ingressi valgono uno. Con due ingressi, il caso più comune, la tabella di verità si racconta a parole, dicendo che zero zero produce zero, zero uno produce zero, uno zero produce zero e soltanto l'ultima combinazione, uno uno, produce uno, da cui il nome, perché la porta chiede questo e anche questo. Il simbolo grafico che trovi qui sotto la raffigura arrotondata da un lato e appuntita dall'altro, con due ingressi dal lato piatto e l'uscita dal vertice.
La terza porta si chiama porta OR e somiglia a un citofono con due pulsanti, per il quale basta premere il sinistro oppure il destro per suonare, infatti la sua uscita vale uno appena un ingresso vale uno, e vale zero soltanto nella combinazione zero zero. La sua tabella di verità produce zero nella prima riga, poi uno in zero uno, uno in uno zero e ancora uno in uno uno, e la OR si rivela la più generosa delle due sorelle, che concede l'uscita uno in tre righe su quattro anziché in una. I tre simboli incontrati qui sopra sono il vocabolario con cui i progettisti disegnano interi processori.
Due sorelle oscure completano la famiglia delle porte classiche, nate dalla voglia di risparmiare transistor, e la prima si chiama porta NAND, che è una AND seguita da una NOT racchiuse nello stesso simbolo, così la sua uscita vale zero soltanto quando tutti gli ingressi valgono uno, cioè esattamente l'opposto della AND. La seconda si chiama porta NOR ed è una OR seguita da una NOT, la cui uscita vale uno soltanto quando tutti gli ingressi valgono zero, e vale zero appena un ingresso qualsiasi si alza. Nella tecnologia dei transistor queste due costano meno delle altre, perché due transistor in serie realizzano direttamente una NAND e due transistor in parallelo realizzano direttamente una NOR, mentre la AND e la OR richiedono un terzo transistor aggiuntivo, ed è per questo che nei progetti veri le porte negate compaiono più spesso delle altre.
Chiudono la famiglia la porta XOR, che abbiamo già incontrato con il nome di OR esclusiva, e la sua negata, chiamata porta XNOR, e conviene fissarle bene perché tornano dappertutto. La XOR vale uno soltanto quando i suoi due ingressi differiscono, il che la rende il confrontatore per eccellenza, e infatti i circuiti che verificano se due parole di bit sono uguali mettono una XOR su ogni coppia di bit e poi raccolgono i risultati, perché se anche una sola coppia differisce la sua XOR alza la mano. La XNOR fa il percorso inverso e vale uno quando gli ingressi sono uguali, il che la rende la candidata naturale nei circuiti che cercano la coincidenza. C'è infine un impiego nascosto ma quotidiano della XOR, perché la somma di due bit vale uno esattamente nelle stesse righe in cui la XOR vale uno, e questo la trasforma nella protagonista silenziosa di ogni circuito che somma.
C'è una proprietà della NAND che merita un piccolo capitolo a parte, ed è la sua capacità di fingersi qualsiasi altra porta, un talento che gli addetti chiamano completezza funzionale e che vale la pena raccontare con calma. Per costruire una NOT basta una NAND i cui due ingressi vengano tenuti uniti, perché rovesciare il valore di un segnale confrontato con se stesso produce proprio l'ingresso negato. Per costruire una AND si prendono due NAND, la prima fa il suo lavoro abituale e la seconda, con gli ingressi uniti, funge da invertitore che cancella la negazione finale. Per costruire una OR si rovesciano prima i due ingressi con due NAND usate come NOT e poi si uniscono i risultati in una terza NAND, e per la legge di De Morgan che abbiamo incontrato poco sopra questa combinazione produce esattamente la OR. Con queste tre mosse la NAND da sola basta a fabbricare un intero calcolatore, e lo stesso talento appartiene alla NOR, il che spiega perché nei circuiti integrati reali le porte economiche siano le vere protagoniste.
Le porte non sono creature magiche, sono fatte dei pezzi che conosci già, e la NOT lo dimostra bene, perché si costruisce con una resistenza e un transistor, il nostro interruttore comandato. La resistenza va tra l'alimentazione e il punto di uscita, il transistor tra questo e la terra, e poi basta osservare. Con l'ingresso basso il transistor resta spento e non lascia passare corrente, per cui la resistenza tira l'uscita verso l'alto, mentre con l'ingresso alto il transistor si accende e scarica l'uscita verso terra. L'ingresso basso produce quindi l'uscita alta e l'ingresso alto produce l'uscita bassa, che è il rovesciamento della NOT, e la resistenza serve a tenere a freno la corrente ed evitare che il transistor si surriscaldi. Lo schema elettrico che trovi qui sotto mostra questa costruzione nei suoi particolari essenziali.
La AND si costruisce in modo analogo con due transistor uno dopo l'altro in serie, come due serrature allineate sullo stesso percorso, e lo schema che trovi qui sotto mostra questa versione essenziale. Con entrambi gli ingressi alti i due transistor si accendono insieme e l'uscita viene scaricata verso terra, mentre appena un ingresso si abbassa il transistor corrispondente si spegne, il collegamento verso terra si interrompe e l'uscita torna alta, comportamento quasi da AND, con un piccolo rovesciamento che si corregge accostando un terzo transistor come invertitore, come racconta Tanenbaum, e la AND completa richiede tre transistor in tutto.
Fermiamoci un attimo per assaporare la rivelazione, perché questi mattoncini di pochi transistor si ripetono dentro un processore moderno miliardi di volte, in uno spazio più piccolo di un francobollo, e ogni blocco copia, sposta, rovescia e combina bit milioni di volte al secondo, il che significa che programmi, pagine e film alla fine si riducono a un fiume di zeri e di uno che attraversano porte logiche.
Finora le porte hanno lavorato da sole come artigiane, ma la vera forza del livello logico digitale emerge quando vengono composte in circuiti combinatori, reti nelle quali il valore di ogni uscita dipende soltanto dai valori presenti in quel momento sugli ingressi, senza memoria del passato e senza attese. Tre di questi circuiti valgono la pena di essere conosciuti per nome, perché ritorneranno quando parleremo di memorie e di processori, e sono il decodificatore, il multiplexer e il demultiplexer.
Il decodificatore (decoder in inglese) accetta un numero di n bit in ingresso e dispone di due alla n uscite, e accende una sola uscita alla volta, quella il cui numero coincide con la combinazione degli ingressi, spegnendo tutte le altre. Il suo comportamento ricorda il centralino telefonico di un palazzo, nel quale componi il numero di un appartamento e squilla un solo campanello, lasciando in pace tutti i vicini. Quando gli ingressi sono tre, come nel caso più semplice che si disegna sui libri, le uscite sono otto, e ogni linea di uscita è una AND abilitata da una diversa combinazione dei tre ingressi, così la combinazione zero uno uno accende solo la quinta linea. Il decodificatore serve dovunque occorra scegliere un componente tra tanti, e il suo impiego più importante è la memoria, dove gli n bit dell'indirizzo vengono decodificati per abilitare una sola cella tra milioni.
Il multiplexer risolve un problema speculare, avendo due alla n linee di ingresso dati, n linee di controllo e una sola uscita, e la sua funzione è scegliere quale dei segnali di ingresso instradare verso l'uscita, esattamente come le leve dello scambio in una stazione ferroviaria decidono quale binario viene collegato al binario principale. Con tre linee di controllo il multiplexer sceglie tra otto ingressi, e il trucco interno è fatto di porte AND ognuna abilitata da una diversa combinazione dei controlli, seguite da una OR che raccoglie il segnale scelto, mentre le altre AND producono zero e restano in silenzio. Il suo impiego più familiare è la tastiera, dove i bit generati da ogni tasto vengono spediti uno dopo l'altro lungo un unico filo invece di occupare otto fili. Il demultiplexer fa il percorso inverso, ricevendo un segnale solo e instradandolo verso una delle sue tante uscite in base ai controlli, e la coppia insieme governa ogni incrocio di dati dentro la macchina.
Veniamo ora al salto più profondo di tutto il capitolo, quello che trasforma i circuiti da calcolatori senza memoria in macchine capaci di ricordare, e comincia con un fatto curioso, dato che finora ogni porta ha dimenticato istantaneamente ciò che riceveva, mentre un circuito con due porte NOR incrociate, ognuna con l'uscita collegata a un ingresso dell'altra, si comporta in modo nuovo e tiene il suo stato anche dopo che gli ingressi se ne sono andati. Questo circuito si chiama latch SR, dove S sta per impostare e R per azzerare, e funziona come un piccolo cancello con due comandi, perché un impulso momentaneo su S porta l'uscita Q a uno e la sua gemella complementare a zero, trascinando l'altra porta nel nuovo stato, e quando l'impulso finisce l'incrocio tra le due porte sostiene da solo la nuova situazione, come due persone appoggiate una all'altra che si reggono a vicenda.
Il latch SR ha un vizio, perché se entrambi i comandi valgono uno nello stesso istante il circuito diventa imprevedibile, e gli ingegneri lo hanno domato aggiungendo un ingresso di abilitazione pilotato da un orologio interno, detto clock, che lascia passare i comandi soltanto quando vale uno. Da lì nasce il latch D, che campiona il valore presente sul suo unico ingresso D nel momento esatto in cui il clock glielo permette e lo conserva, diventando una memoria a un bit completa e disciplinata, e Tanenbaum osserva che una versione siffatta richiede circa undici transistor, con varianti più raffinate che scendono a sei. Il passo finale lo compie il flip-flop, che si distingue dal latch per il fatto di cambiare stato soltanto sul fronte del clock, cioè nell'istante esatto in cui il segnale di orologio passa da zero a uno, anziché durante tutto il tempo in cui il clock resta alto, e questa precisione lo rende l'atomo delle memorie sincrone dei calcolatori moderni.
Una volta ottenuto il flip-flop, costruire una memoria più capace è questione di pazienza, perché allineandone trentadue uno accanto all'altro e dando a tutti lo stesso clock si ottiene un registro, una piccola cassettiera che conserva trentadue bit insieme e li aggiorna tutti nello stesso istante, trattenendo una parola intera del linguaggio della macchina. I registri vivono nel cuore del processore, dove sono pochi e velocissimi, e capire che sono fatti di semplici flip-flop costruiti con porte, porte costruite con transistor, e transistor costruiti con silicio e droghe chimiche, chiude il cerchio di questo capitolo e apre direttamente la porta della prossima pagina, dove li incontreremo all'opera.
Per vedere come i mattoni diventino calcoli cominciamo dalla somma, l'operazione più umile e indispensabile, dato che è impossibile immaginare un calcolatore che non sappia addizionare. Sommare due bit chiede due risposte, la somma e il riporto per la colonna successiva, e la sua tabella di verità dice che zero più zero dà somma zero e riporto zero, zero più uno dà somma uno e riporto zero, uno più zero dà somma uno e riporto zero e uno più uno dà somma zero e riporto uno, perché uno più uno fa dieci in binario, zero nella colonna e uno oltre, come nove più uno in decimale. Il circuito con queste due risposte si chiama mezzo sommatore, di una semplicità commovente, perché la somma la dà una porta XOR, che vale uno solo quando i due ingressi differiscono, mentre il riporto spetta a una semplice AND, attiva quando entrambi gli ingressi valgono uno.
Il mezzo sommatore sa sommare soltanto la prima colonna, quella più a destra, perché ignora il riporto che arriva dalle colonne vicine, e per questo i progettisti lo raddoppiano, unendo due mezzi sommatori con una OR e ottenendo il sommatore completo, che accetta anche il riporto della colonna precedente. Incatenandone uno per colonna si ottiene il sommatore a propagazione di riporto (ripple carry in inglese), nel quale il riporto, come un testimone, attraversa la parola da destra verso sinistra, e questo schema funziona benissimo ma soffre di un vizio di lentezza, perché nel caso peggiore, sommando uno a una parola fatta tutta di uno, l'ultima colonna resta in attesa che il riporto le raggiunga attraverso tutte le precedenti.
Per guarire questa lentezza esistono sommatori più intelligenti, e il più celebre si chiama sommatore con anticipazione del riporto (carry lookahead in inglese), un circuito che lo guarda arrivare prima che la corsa cominci. Ogni colonna, esaminando i propri due bit, sa in anticipo se genererà da sola un riporto, quando entrambi valgono uno, oppure se si limiterà a propagare quello che le arriva, quando uno solo vale uno, e un circuito aggiuntivo calcola così tutti i riporti in parallelo, così l'ultima colonna riceve il suo quasi istantaneamente. Lo schema qui sotto disegna un sommatore rapido a quattro bit, con le linee dedicate alla generazione e alla propagazione dei riporti, e la lezione è che la pazienza si compra con un pizzico di circuiti in più.
Resta un problema di buon senso da risolvere, perché finora abbiamo sommato soltanto numeri positivi,
mentre la vita chiede anche di fare i conti coi valori sotto lo zero, e il primo tentativo storico fu il
sistema di segno e grandezza, nel quale il bit più a sinistra si riserva al segno e gli altri contano il
valore, una soluzione che nasconde due guai, dato che esistono due zeri diversi e le somme richiedono
regole speciali che complicano i circuiti. La vittoria definitiva arrivò con il complemento a
due, un trucco elegante che permette di rappresentare i negativi senza modificare di una porta il
sommatore che abbiamo già costruito. Su quattro bit i numeri positivi vanno da zero, scritto
0000, fino a sette, scritto 0111, e per scrivere un negativo si prende il
valore positivo, si rovesciano tutti i bit e si aggiunge uno alla fine, così il cinque, che è
0101, diventa 1010 dopo il rovesciamento e 1011 dopo l'aggiunta,
e proprio quella stringa rappresenta il meno cinque. La magia si vede sommando, perché cinque più meno
cinque, cioè 0101 più 1011, dà 10000, e il quinto bit, che su
quattro bit non esiste, viene semplicemente scartato lasciando 0000, cioè zero esatto.
Questa economia di mezzi ha però un conto da pagare, ed è un piccolo disastro numerico che i
progettisti chiamano overflow, l'eccedenza che nasce quando un risultato non ci sta nella
larghezza a disposizione. Sommando sette e due su quattro bit il risultato nove richiederebbe quattro
bit più un quinto, e il sommatore, che conosce soltanto quattro posizioni, ricomincia il giro come un
contachilometri di automobile che passa da 99999 a 00000, mostrando 1001 che su quattro
bit in complemento a due vale meno sette, e il calcolo, pur essendo giusto per il circuito, diventa
sbagliato per noi. I calcolatori seri per questo custodiscono un apposito bit di overflow, che si alza
ogni volta che la somma di due numeri con lo stesso segno produce un risultato dal segno opposto, e il
programmatore, in un modulo futuro sulla programmazione, imparerà a temerlo e a rispettarlo.
Uniamo adesso tutti i pezzi e otteniamo la macchina aritmetica intera, che nei libri si presenta come unità aritmetica e logica, detta ALU dalle sue iniziali inglesi. Guardiamone la versione a un bit, che è un capolavoro di ingegneria didattica, perché contiene una AND e una OR sui due ingressi A e B, un sommatore completo per la somma, e un piccolo decodificatore che, in base alle linee di controllo, abilita una sola delle uscite interne a passare attraverso la porta OR finale, un po' come scegliere quale rubinetto aprire in un banco di cucina con più tubi. Per ottenere l'unità a n bit basta replicare il circuito a un bit per ogni posizione e collegare i riporti in cascata da destra verso sinistra, e con questa mossa la macchina sa sommare, confrontare e manipolare bit a comando, il che è tutto ciò che serve per costruire il resto del computer.
Una macchina che sa trattare bit e numeri diventa utile a noi quando impara a parlare la lingua dei
testi, e la prima lingua standard fu il codice ASCII, nato per le telemacchine e sopravvissuto
fino a oggi, che assegna a ogni lettera, cifra e segno un numero di sette bit. Il gioco consiste nel
fissare una convenzione condivisa, così la lettera A maiuscola vale 65, che in binario si scrive
1000001, la B vale 66, lo spazio vale 32 e la cifra zero vale 48, e quando il testo
viaggia o viene conservato nella memoria è questa sfilza di numeri che viene copiata, fissata e
trasmessa, mentre sullo schermo il carattere compare solo grazie a un programma che ritrasforma i
numeri in disegni. I primi trentadue codici sono caratteri di controllo pensati per comandare le
macchine, come il ritorno a capo o la campanella, e tutti insieme fanno centoventotto, quanti ne
bastano per l'inglese tecnico.
Il mondo però scrive in centinaia di alfabeti, e per accoglierli tutti è nato il codice UTF-8, che usa da uno a quattro byte per ogni carattere e lascia immutati i primi centoventotto codici dell'ASCII, così i vecchi testi funzionano ancora mentre i caratteri cinesi, arabi ed emoji occupano più spazio soltanto quando serve. Chiudiamo il capitolo con il primo eroe della correttezza dei dati, il bit di parità, un controllore d'errore rudimentale ma geniale, che aggiunge a ogni gruppo di bit un bit extra scelto in modo che il numero complessivo di uno sia dispari, e quando il gruppo arriva a destinazione il ricevente conta di nuovo e, se il totale torna pari, capisce che qualche bit si è rovesciato durante il viaggio e suona l'allarme. Il bit di parità riesce ad accorgersi di un errore singolo e si arrende davanti a due errori insieme, eppure per decenni ha vegliato sulle memorie dei calcolatori, dimostrando che anche un'idea da poche porte può difendere milioni di dati.
La teoria, per quanto raccontata con calma, lascia un velo di nebbia finché resta soltanto letta, quindi adesso appoggia la spiegazione e vieni a sporcarti le mani con sette esperimenti, i primi cinque con un foglio e una penna e gli ultimi due nel simulatore del browser, ordinati dal più semplice al più articolato.
Prendi un foglio bianco e scrivi da solo le tabelle di verità di NOT, AND e OR, cominciando dalla NOT, per la quale bastano una riga con ingresso zero e una con ingresso uno, poi passando alla AND e alla OR, per le quali esamini tutte e quattro le combinazioni degli ingressi, zero zero, zero uno, uno zero e uno uno. Scrivi accanto a ogni riga il valore atteso e confrontalo con le frasi del testo, perché scoprire con la propria penna che la AND concede l'uscita uno soltanto nell'ultima riga e che la OR la concede soltanto dopo la prima è un atto di comprensione che la sola lettura non regala.
Per il secondo esperimento resta sul foglio e somma a mano due numeri binari a quattro bit, per
esempio 0110 più 0101, colonna per colonna da destra verso sinistra, portando
il riporto come alle elementari, così che nella prima colonna zero più uno dà uno senza riporto, nella
seconda uno più zero dà ancora uno, nella terza uno più uno dà zero lasciando un riporto, e nell'ultima
quel riporto, sommato a due zeri, dà uno, e il risultato, 1011, si verifica in un lampo in
decimale, perché 0110 vale sei e 0101 vale cinque.
Per il terzo esperimento prendi il tuo anno di nascita e convertilo in binario usando la bilancia dei pesi, scrivendo sopra una riga i pesi uno, due, quattro, otto, sedici, trentadue, sessantaquattro, centoventotto, duecentocinquantasei, cinquecentododici, milleventiquattro e duemilaquarantotto, e poi accendendo da sinistra i pesi che ci stanno nel numero, come hai visto fare con il tredici nel testo. Quando la fila di zeri e uno è pronta raggruppa i bit a quattro a quattro partendo da destra e traduci ogni gruppo nella sua cifra esadecimale, e divertiti a notare come i programmatori leggono al volo il risultato finale, perché un numero lunghissimo di bit diventa una parolina di quattro o cinque caratteri.
Il quarto esperimento torna sul foglio per domare il complemento a due a mano, partendo dal numero
cinque su quattro bit, 0101, rovesciando ogni bit per ottenere 1010 e
aggiungendo uno per arrivare a 1011, che è il meno cinque. Per mettere alla prova il
trucco somma poi 0101 e 1011 colonna per colonna come nel secondo
esperimento, osserva il quinto bit che sbuca fuori e scartalo senza pietà, e davanti a
0000, cioè lo zero esatto, apprezza per un istante l'eleganza di un gioco in cui sottrarre
diventa un caso particolare di sommare.
Per il quinto esperimento torna alla tabella dei codici ASCII, che trovi documentata in molti posti e che il capitolo ti ha raccontato, e scrivi a mano il tuo nome o una parola corta di tua scelta prima in numeri decimali e poi in binario a sette bit, spaziando i gruppi per leggerli comodamente. Confronta infine la tua trascrizione con quella che produce il computer usando un qualsiasi convertitore di testo in binario, e osserva come la sequenza che hai tracciato con la penna coincide con quella che la macchina usa quando salva il file, perché la convenzione è la stessa per tutti.
Il sesto esperimento si svolge nel simulatore di porte logiche del browser, per esempio quello libero di CircuitVerse, dove puoi verificare con le mani la completezza della NAND costruendo prima una NOT collegando insieme i suoi due ingressi, poi una AND mettendo davanti a una NAND una seconda NAND con gli ingressi uniti, e infine una OR rovesciando i segnali con due NAND usate come NOT prima dell'ultima NAND. Commuta gli interruttori e confronta ogni tabella di verità con quella scritta sul foglio nel primo esperimento, e se le righe coincidono hai fabbricato con le tue mani virtuali tutta l'algebra di Boole a partire da un solo tipo di porta, esattamente come fanno i circuiti integrati reali.
Il settimo e ultimo esperimento è il più commovente, perché nel simulatore puoi far nascere la memoria, collegando due porte NOR in un latch SR con gli incroci che Tanenbaum descrive, e poi premendo per un istante il pulsante di impostazione e togliendolo, osservando che l'uscita resta accesa come se il circuito si fosse ricordato del tuo tocco. Premi poi il pulsante di azzeramento, osserva il cambiamento, togli anche quello, e contempla il fatto che il valore resta dov'è senza nessuno che lo tenga, il che è esattamente ciò che fa la memoria del tuo computer ogni volta che salvi un file.
Questa pagina attinge soprattutto al capitolo sull'algebra di Boole, sulle porte logiche, sui circuiti combinatori e sulla memoria elementare del libro Architettura dei calcolatori di Andrew S. Tanenbaum, con qualche passaggio dall'appendice sull'aritmetica binaria, dove le stesse idee ricevono veste rigorosa, e ora che conosci i mattoni, dal NOT che ribalta alla XOR che confronta, il passo successivo li posa uno accanto all'altro secondo i disegni dell'algebra di Boole, motivo per cui la prossima pagina è dedicata ai circuiti combinatori e puoi raggiungerla da qui quando ti senti pronto.