6

Non conta

Gandhi è famoso come il pacifista che guidò l’India nella conquista dell’indipendenza dal Regno Unito; dal 1991, però, si è anche fatto la reputazione di essere un leader guerrafondaio pronto a lanciare attacchi nucleari non provocati. Questo a causa dei videogiochi della serie Civilization, che hanno venduto più di 33 milioni di copie. Lo scopo del gioco consiste nel costruire la più grande civiltà del mondo confrontandosi con diversi leader storici, uno dei quali è proprio il pacifico (normalmente, almeno) Gandhi. Sennonché, fin dalle prime versioni di Civilization, i giocatori notarono che Gandhi era, come dire, un po’ stronzo: non appena metteva a punto la tecnologia atomica, iniziava a sganciare bombe nucleari sulle altre nazioni.

Ciò era dovuto a un errore nel codice informatico del gioco. I programmatori avevano deliberatamente assegnato a Gandhi il valore di aggressività più basso possibile (diverso da zero): 1 punto. Il Gandhi classico, insomma. Tuttavia, andando avanti nel gioco, quando tutte le civiltà diventavano più – ehm… – civilizzate, il punteggio di aggressività di ogni leader calava di 2. Nel caso di Gandhi, che partiva da 1, il risultato era 1 − 2 = 255, cosa che gli dava all’improvviso la massima aggressività possibile. In seguito questo errore è stato corretto ma, per tradizione, anche le versioni successive del gioco hanno comunque lasciato che Gandhi rimanesse il leader più incline a ricorrere alle armi nucleari.

Il risultato di quella sottrazione era 255 per la stessa ragione per cui i computer hanno difficoltà a tenere il conteggio del tempo: la memoria digitale è limitata. I valori di aggressività erano memorizzati come un numero binario di 8 cifre. Se partiamo da 00000001 togliamo due unità, otteniamo prima 00000000 e quindi 11111111 (che nei normali numeri in base 10 corrisponde a 255). Invece di diventare negativo, un numero memorizzato in un computer si riavvolge su se stesso arrivando al massimo valore possibile. Si tratta dei cosiddetti errori di «roll-over» («ripartire da capo»), che possono colpire il codice informatico in modi davvero interessanti.

In Svizzera, i treni non possono avere 256 assi. Questo potrà anche essere un fatto molto misterioso, ma non può comunque essere citato come un esempio delle follie dei regolamenti europei. Per tenere traccia della posizione di tutti i treni che circolano sulla rete ferroviaria svizzera, ci sono dei rilevatori collocati lungo i binari. Il loro funzionamento è molto semplice: si attivano quando una ruota passa su un binario e contano il numero delle ruote per fornire alcune informazioni di base sul treno appena passato. Purtroppo, per tenere il conteggio delle ruote usano un numero binario a 8 cifre, che quando raggiunge il valore di 11111111 ritorna a 00000000; di conseguenza, un treno con 256 assi di ruote riporterebbe i contatori esattamente a zero e si muoverebbe senza lasciare tracce, come un treno fantasma.

Ho controllato una recente copia dei regolamenti ferroviari svizzeri e la norma sui 256 assi si trova tra quelle sui carichi portati sui treni e quelle sui modi in cui i capitreno possono comunicare con i macchinisti.

La norma si può tradurre con: «Per evitare il pericolo che su una sezione di ferrovia venga dato un segnale non intenzionale di via libera a causa dell’azzeramento del contatore degli assi, un treno non deve avere un numero totale effettivo di assi pari a 256».

La norma si può tradurre con: «Per evitare il pericolo che su una sezione di ferrovia venga dato un segnale non intenzionale di via libera a causa dell’azzeramento del contatore degli assi, un treno non deve avere un numero totale effettivo di assi pari a 256».

Immagino che le autorità ferroviarie svizzere abbiano ricevuto talmente tante domande da parte delle persone che volevano conoscere l’esatto motivo della proibizione di quel 256° asse che, alla fine, si sono decise a inserire una giustificazione nel manuale. Una soluzione, a quanto pare, più facile che sistemare il codice. Ci sono stati innumerevoli casi in cui un problema hardware è stato risolto tramite un aggiornamento software, ma solo in Svizzera ho visto un bug sistemato con una patch burocratica.

Gli errori roll-over possono essere affrontati in diversi modi. Se i programmatori vedono all’orizzonte un problema relativo al numero 256, possono inserire un limite fisso per impedire che i valori superino il 255. È una cosa che avviene ovunque, ed è divertente vedere come le persone siano disorientate di fronte a queste soglie in apparenza arbitrarie. Quando WhatsApp ha alzato da 100 a 256 il limite degli utenti che possono trovarsi in una stessa chat di gruppo, la modifica è stata riportata sull’«Independent» con il commento «Non è chiaro perché WhatsApp abbia scelto proprio questo strano, specifico numero».

Un sacco di persone, però, lo sapevano benissimo. Quel commento sparì in fretta dalla versione online del quotidiano, con una nota a piè di pagina che spiegava che «Numerosi lettori ci hanno fatto notare che 256 è uno dei numeri più importanti nel campo informatico». Provo una certa compassione per chi, quel pomeriggio, aveva il compito di rispondere sul loro account di Twitter.

Questa strategia è ciò che chiamo la «soluzione del muro di mattoni». Se siete in un gruppo di WhatsApp con 256 persone (voi e 255 amici) e cercate di aggiungere qualcun altro, il programma, semplicemente, vi impedirà di farlo. Ma dato che, in sostanza, state affermando di avere 255 amici migliori di quello escluso, il vostro legame con quest’ultimo non sarà probabilmente così stretto da far sì che possa prenderla sul personale. Il pericolo di un errore roll-over è anche il motivo per cui nel gioco Minecraft c’è un limite massimo di altezza di 256 blocchi (che costituisce una soluzione del muro di mattoni proprio nel senso letterale dell’espressione).

Un altro modo di affrontare gli errori roll-over consiste nel riavvolgere il contatore in modo che a 11111111 segua 00000000. Questo è esattamente ciò che accade in Civilization e sulla rete ferroviaria svizzera, solo che lì si trattava di effetti a catena non intenzionali. I computer si limitano a seguire ciecamente le regole che vengono date loro e a fare la cosa «logica», senza preoccuparsi di quella che potrebbe essere la cosa «ragionevole». Ciò significa che quando scriviamo un codice informatico dobbiamo cercare di tener conto di ogni possibile esito e di assicurarci che al computer venga detto quello che dovrà fare. Sì, la programmazione richiede una preparazione matematica e scientifica, ma per me a unire di più i programmatori e i matematici è la capacità di pensare logicamente considerando i diversi possibili scenari.

I programmatori della versione originale da bar di Pac-Man avevano scelto di memorizzare il livello sotto forma di un numero binario di 8 cifre che sarebbe ripartito da capo una volta raggiunto il valore massimo. Però si dimenticarono di fare un’analisi di tutte le conseguenze di quella decisione; così, una volta raggiunto il livello 256, una complessa catena di anomalie finisce per mandare in tilt il gioco. Non che sia una gran perdita, comunque: anche solo 255 livelli funzionanti sembrano troppi, vedendo come la maggior parte delle persone non arrivano mai oltre il primo. Ma per chi ha tempo e monetine da spendere, ci sono centinaia di livelli da esplorare (va comunque riconosciuto che sono tutti identici, a parte il comportamento dei fantasmini). Detto questo, il livello più alto che ho raggiunto è il 7. Devo migliorare.

Il livello 256 è un caos totale. Pare che anche i poveri fantasmini abbiano un’aria smarrita.

Il livello 256 è un caos totale. Pare che anche i poveri fantasmini abbiano un’aria smarrita.

Il gioco non va in crisi al livello 256 perché non è in grado di memorizzare il numero del livello. Come sempre, i programmatori iniziano a contare da zero, quindi il livello 1 è memorizzato come indice 0, il livello 2 come indice 1 e così via (uso il termine «indice» per riferirmi al numero memorizzato, diverso dal numero effettivo del livello). Il livello 256 è perciò registrato come indice 255, che in binario corrisponde a 11111111. Nessun problema, quindi. Anche passare al livello 257 significherebbe solo far ritornare l’indice a zero e riportare Pac-Man al primo labirinto. Il gioco dovrebbe poter continuare all’infinito. Perché, allora, al livello 256 impazzisce?

Il problema è la frutta. Per aggiungere un po’ di varietà alla dieta a base di puntini e fantasmini di Pac-Man, ci sono otto diversi tipi di frutti che appaiono due volte per ogni livello (inclusa una campana e una chiave, che non saranno proprio frutti ma che Pac-Man sembra comunque mangiare con la stessa facilità con cui ingoierebbe una mela o una fragola). A ciascun livello è assegnato uno specifico frutto, mostrato in fondo allo schermo insieme alla frutta appena consumata da Pac-Man. È proprio questa parata ornamentale di frutti a mandare in tilt il gioco.

Nei vecchi sistemi informatici, lo spazio digitale era talmente un lusso che, mentre giocate a Pac-Man, in memoria vengono salvati soltanto tre numeri: il livello in cui vi trovate, il vostro punteggio e quante vite vi restano. Tutto il resto viene cancellato nel passaggio da un livello a quello successivo. In ciascuno, giocate contro fantasmini smemorati che non hanno nessuna idea di cosa sia successo nelle ore di battaglia precedenti. Il gioco, cioè, dev’essere in grado di ricostruire da zero quale frutta Pac-Man ha consumato di recente. Dato che lo spazio è sufficiente a rappresentare solo sette singoli frutti, il gioco deve mostrare la frutta dell’attuale livello e quella dei sei livelli precedenti (a seconda di quanti ne avete giocati).

Nella memoria del computer c’è un menu della frutta e l’ordine in cui può apparire. Così, se il livello è inferiore a 7, il computer disegna un numero di frutti pari a quello del livello; superato quel livello, disegnerà i sette frutti più recenti. Il problema si verifica quando il codice converte l’indice che rappresenta il livello in un numero di livello più 1. Il livello 256 è l’indice 255, che aumentato di uno diventa il… livello 0. Zero è minore di sette, così il computer cerca di disegnare un numero di frutti pari a quello del livello. L’operazione non presenterebbe problemi se disegnasse zero frutti ma, ahimè, prima disegna e dopo conta: il codice, cioè, disegna il frutto e poi sottrae uno dal numero del livello, finché non raggiunge lo zero.

Disegna il frutto

Sottrai 1 dal numero del livello

Fermati se il numero del livello è zero

Altrimenti, CONTINUA A PRODURRE FRUTTI

Questo non è il vero codice di Pac-Man, comunque rende l’idea.

Il computer tenterà ora di disegnare 256 frutti al posto dei normali sette o meno. Be’, ho detto «frutti», ma di fatto il menu della frutta finisce dopo sole venti righe. Quindi, per disegnare il ventunesimo frutto, il codice cerca nella parte successiva della memoria del computer e tenta di interpretare ciò che vi trova come frutto; poi continua a far scorrere la memoria come se fosse una sorta di tabella esotica di frutta aliena e la disegna per intero, al meglio delle sue possibilità. Alcuni di questi frutti corrispondono ad altri simboli mostrati nel gioco, così che, oltre che di pittoreschi caratteri indistinti, lo schermo si riempie anche di lettere e segni di punteggiatura.

A causa di una peculiarità del sistema di coordinate di Pac-Man, dopo che la frutta ha riempito il fondo dello schermo da destra a sinistra, si sposta all’angolo in alto a destra e inizia a riempire lo schermo colonna dopo colonna. Una volta disegnati i 256 frutti, metà dello schermo risulta completamente coperta. A quel punto, incredibilmente, il gioco fa partire il livello come niente fosse, ma il problema è che per il sistema un livello non è completo finché Pac-Man non ha mangiato 244 puntini; e in quest’ultimo livello buggato, la frutta mutante ha fatto sparire un sacco di puntini, motivo per cui Pac-Man non sarà mai in grado di mangiare i 244 richiesti e sarà condannato a vagare per ciò che resta del suo labirinto finché la noia non avrà la meglio e soccomberà ai fantasmini che gli danno la caccia. Una sensazione che, casualmente, coincide quasi del tutto con quella provata da un sacco di programmatori mentre tentano di finire di scrivere il loro codice.

Codici letali

Il più pericoloso errore 256 che ho incontrato finora è quello che si verificava con la macchina per la radioterapia Therac-25. Quest’apparecchiatura era progettata per trattare i pazienti affetti da cancro esponendoli a un fascio di elettroni oppure a raggi X ad alta energia. Per produrre i due diversi tipi di radiazioni, la macchina poteva generare un fascio di elettroni a bassa corrente a cui il paziente veniva direttamente esposto oppure un fascio di elettroni ad alta corrente che veniva sparato contro una piastra metallica in modo da produrre raggi X.

Il pericolo era costituito dal fatto che il fascio di elettroni richiesto per la produzione dei raggi X era talmente potente da provocare gravi danni a un soggetto che ne fosse stato colpito direttamente; pertanto, se la potenza del fascio di elettroni veniva aumentata, era di vitale importanza assicurarsi che la piastra metallica e un collimatore (un filtro per dar forma al fascio di raggi X) fossero stati prima collocati tra il fascio di elettroni e il paziente.

Per questo, e per tutta un’altra serie di ragioni di sicurezza, la Therac-25 aveva un codice informatico che prevedeva un ciclo di controlli, e il fascio poteva essere acceso soltanto dopo che era stata verificata la corretta impostazione di tutti i sistemi. Il software aveva un valore memorizzato sotto l’accattivante nome di «Class3» (cosa che rende bene l’idea di quanto i programmatori sappiano essere creativi nel dare un nome alle loro variabili). Solo dopo aver verificato la sicurezza di tutti i sistemi, la Therac-25 poneva Class3 = 0.

Per assicurarsi che i controlli venissero sempre fatti, il codice aggiungeva un’unità a Class3 all’inizio di ogni ciclo, in modo che dovesse partire da un valore diverso da zero. Una subroutine chiamata «Chkcol» (come nome è un po’ meglio) si attivava ogni volta che Class3 era diversa da zero e controllava quindi il collimatore; una volta verificato che quest’ultimo e la piastra di metallo si trovavano nella posizione corretta, Class3 poteva prendere il valore di zero e il fascio poteva essere acceso.

Purtroppo, il valore della variabile Class3 era memorizzato come un numero binario di 8 cifre che ritornava a zero dopo aver raggiunto il massimo; e i cicli di controllo venivano fatti più e più volte nell’attesa che tutto fosse pronto, con il valore di Class3 che continuava quindi a crescere a ogni ciclo. Di conseguenza, ogni 256 cicli Class3 prendeva il valore di zero non perché la macchina fosse in condizioni di sicurezza ma semplicemente perché, dopo aver raggiunto il valore massimo di 255, il numero si era azzerato.

Ciò significa che, in circa lo 0,4 per cento dei casi, una macchina Therac-25 saltava la subroutine Chkcol perché Class3 era pari a zero, come se il collimatore fosse già stato controllato e la correttezza della sua posizione fosse già stata confermata. Per un errore dalle conseguenze così letali, un tasso dello 0,4 per cento è altissimo.

Il 17 gennaio 1987, nello Yakima Valley Memorial Hospital (oggi Virginia Mason Memorial) dello Stato di Washington (USA), un paziente avrebbe dovuto ricevere 86 rad (un’unità di misura delle radiazioni assorbite, oggi non più in uso) di raggi X da una macchina Therac-25; tuttavia, prima che la sua seduta avesse inizio, la piastra metallica e il collimatore erano stati spostati (in modo che l’apparecchiatura potesse essere allineata usando la normale luce visibile) senza che nessuno li risistemasse.

L’operatore premette il pulsante di avvio nel preciso momento in cui la variabile Class3 era tornata a zero: la subroutine Chkcol venne quindi saltata e il fascio di elettroni fu sparato direttamente contro il paziente, senza nessuna piastra o collimatore interposti. Il paziente, che avrebbe dovuto ricevere una dose di 86 rad, ne ricevette tra gli otto e i diecimila; morì qualche mese dopo, ad aprile, in seguito alle complicazioni dovute a quella sovraesposizione.

La patch per risolvere il problema del software si rivelò di una semplicità disarmante: bastò riscriverlo in modo che, a ogni ciclo, il programma assegnasse a Class3 un valore specifico diverso da zero anziché incrementare di un’unità il suo valore precedente. Non prestare attenzione al modo in cui i computer gestiscono i numeri può avere esiti letali; è un pensiero che fa riflettere.

Cose in cui i computer non excellono

Quanto fa 5 − 4 − 1? Non è una domanda trabocchetto: la risposta è zero. Solo che non è sempre facile come sembra: in questo calcolo, per esempio, Excel può sbagliare. Il sistema di cifre binarie usato dai computer per conservare i numeri nella loro memoria digitale non si limita a provocare degli errori roll-over, ma può entrare in crisi anche nei calcoli in apparenza più facili.

Se cambio quel 5 − 4 − 1 in 0,5 − 0,4 − 0,1, la risposta corretta è sempre zero, ma la versione di Excel che sto usando pensa che sia −2,77556E-17. Anche se −0,0000000000000000277556 non è esattamente zero, è comunque straordinariamente vicino a zero; Excel, quindi, sta facendo qualcosa di giusto. Tuttavia, allo stesso tempo sta anche succedendo qualcosa di fondamentalmente sbagliato.

Uhm, questo è davvero strano.

In breve, alcuni numeri causano problemi ai sistemi in base diversa. I nostri normali numeri in base 10, per esempio, sono pessimi nel gestire i terzi, anche se noi ci siamo ormai abituati e siamo in grado di compensare questo difetto. Un rapido calcolo: quanto fa 1 − 0,666666 − 0,333333? Il vostro istinto potrebbe portarvi a rispondere zero, in quanto 1 − 2/3 − 1/3 = 0. Di fatto, però, quelle cifre non rappresentano esattamente 2/3 e 1/3, poiché per farlo dovrebbero avere un numero infinito di sei e di tre. La risposta corretta è quindi 0,000001, un valore che è leggermente diverso da zero a causa del fatto che avevo a disposizione solo uno spazio limitato per le rappresentazioni decimali di 2/3 e 1/3. Allo stesso modo, se sommate 0,666666 e 0,333333, non otterrete 1 ma solo 0,999999.

I numeri binari hanno questo stesso problema con la rappresentazione di alcune frazioni. Nel sistema binario, sommando 0,4 e 0,1 non otteniamo 0,5, ma:

0,4= 0 , 0 1 1 0 0 1 1 0 0 1 1 0 0…

0,1= 0 , 0 0 0 1 1 0 0 1 1 0 0 1 1…

0,4 + 0,1= 0 , 0 1 1 1 1 1 1 1 1 1 1 1 1…

Un computer non è in grado di gestire le infinite cifre delle rappresentazioni binarie di 0,1 e 0,4, quindi la loro somma non è esattamente pari a 1/2.1 Ma proprio come noi umani ci siamo abituati alle limitazioni della base 10, i computer sono stati programmati per correggere gli errori introdotti dai calcoli binari.

Se in Excel inserite semplicemente = 0,5 − 0,4 − 0,1, il programma vi darà la risposta giusta: sa che 0,0111111…, in realtà, dovrebbe essere esattamente uguale a 1/2. Tuttavia, se inserite = (0,5 − 0,4 − 0,1)*1, l’errore non viene più corretto e rimane lì. Excel non controlla questo tipo di errori durante il calcolo, ma soltanto alla fine; così, facendo in modo che l’ultimo passo sia soltanto un’innocente moltiplicazione per uno, abbiamo dato al programma un falso senso di sicurezza, portandolo a non analizzare la risposta prima di darcela.

I programmatori di Excel sostengono che la colpa non è direttamente imputabile a loro: si limitano infatti a aderire agli standard per l’aritmetica fatta dai computer stabiliti dall’Institute of Electrical and Electronics Engineers (IEEE), con solo qualche piccola variazione nel modo in cui vengono gestiti i casi insoliti. L’IEEE ha pubblicato lo standard 754 nel 1985 (l’aggiornamento più recente risale al 2008) con lo scopo di determinare in che modo i computer dovrebbero idealmente affrontare le limitazioni dei calcoli fatti con numeri binari dalla precisione finita.2

Dato che questo problema ha la propria radice negli standard, lo vedrete saltar fuori ogni volta che chiederete a un computer di fare qualche calcolo al posto vostro. Per esempio, in un telefono moderno. Immaginate di essere impegnati a stendere un programma. Che cosa dovreste fare per sapere quanti periodi di due settimane ci sono in settantacinque giorni? La maggior parte delle persone prenderebbe subito l’app calcolatrice sul telefono; eppure, posso garantirvi che siete in grado di risolvere il problema meglio di un calcolatore.

Prendete il telefono e aprite la calcolatrice. Se inserite 75 ÷ 14, sullo schermo apparirà subito la risposta 5,35714286… Così, in settantacinque giorni ci sono poco più di cinque periodi di due settimane. Per calcolare quanti sono i giorni extra, sottraete 5 e moltiplicate ciò che rimane (ossia, lo 0,35714286… di un periodo di due settimane) per 14. Il risultato che vi mostrerà la calcolatrice è però sbagliato.

Su alcuni telefoni, vedrete la risposta 5,00000001 o qualcosa di simile; altri vi daranno un risultato come 4,9999999994. I possessori di un iPhone vedranno la risposta corretta, 5, ma non cantino vittoria troppo presto: basta infatti inclinare l’iPhone di lato, in modo da far passare la calcolatrice alla modalità scientifica, e nelle vecchie versioni di iOS verrà mostrata la risposta completa, 4,9999999999. Ho appena provato a usare la calcolatrice sul mio computer e mi ha risposto 5,00000000000004. A causa delle limitazioni del sistema binario, i computer vanno sempre vicini al risultato corretto, ma senza arrivarci del tutto. Come ogni prodotto alimentare che ha un «diet» nel proprio nome, non raggiungono mai pienamente il bersaglio.

I pericoli del troncamento

Nei teatri di guerra, ogni errore banale può portare alla perdita di molte vite. E anche se le guerre sono inscindibilmente intrecciate con la politica, penso che sia comunque possibile esaminare con obiettività come degli errori matematici altrimenti piccoli possano avere risultati disastrosi nei termini del loro costo in vite umane. Persino quando si parla di uno sbaglio matematico minuscolo, come un errore dello 0,00009536743164 per cento.

Il 25 febbraio 1991, durante la Prima guerra del Golfo, un missile Scud venne lanciato contro la caserma dell’esercito americano vicino a Dhahran, in Arabia Saudita. L’attacco non fu una sorpresa per l’US Army, che aveva allestito un «sistema di difesa missilistico Patriot» allo scopo di individuare, tracciare e intercettare i missili nemici come quello. Usando il radar, il sistema Patriot era in grado di individuare un missile in arrivo, calcolare la sua velocità e utilizzare quel dato per seguire i suoi movimenti fino a quando non entrava nel raggio d’azione delle batterie antimissile, che potevano lanciare un missile per distruggerlo. Questo in teoria, almeno: in pratica, a causa di una svista matematica nel codice, il missile terra-aria Patriot mancò lo Scud.

Progettata in origine come un sistema mobile per l’intercettazione degli aerei nemici, la batteria Patriot era stata aggiornata in tempo per la guerra del Golfo così da poter essere impiegata contro i missili Scud, molto più veloci, in grado di viaggiare all’impressionante velocità di circa 6000 km/h. Inoltre, i Patriot usati nel Golfo erano schierati in posizioni statiche anziché essere spostati di qua e di là, come prevedeva il loro progetto originale.

Rimanendo stazionari, i loro sistemi non venivano ripetutamente accesi e spenti (cosa che, come abbiamo già visto, può portare a qualche problema con il conteggio interno del tempo). Il sistema usava un numero binario di 24 cifre (24 bit, 3 byte) per contare il tempo in decimi di secondo dal momento del suo ultimo avvio, il che significava che poteva restare acceso per 19 giorni, 10 ore, 2 minuti e 1,6 secondi prima di incorrere in un errore roll-over; un lasso di tempo che, quando erano stati progettati, doveva essere sembrato molto lungo.

Il problema stava nel modo in cui quel numero di decimi di secondo veniva convertito in un valore in virgola mobile che esprimeva i secondi esatti. La matematica di questa operazione è piuttosto semplice: si moltiplica il valore per 0,1 così da dividerlo di fatto per dieci. Nel sistema Patriot, però, 1/10 era rappresentato come un numero binario a 24 bit, e questo creava lo stesso problema che si manifesta in Excel quando sottraiamo 0,4 e 0,1 da 0,5: il risultato è sbagliato, anche se di pochissimo.

0,00011001100110011001100 (base 2) =

0,099999904632568359375 (base 10)

0,1 − 0,099999904632568359375 =

0,000000095367431640625

Questo è il valore assoluto dell’errore per 0,1 secondo, che corrisponde a un errore dello 0,000095367431640625 per cento.

Un errore dello 0,000095 per cento potrà non sembrare una gran cosa; in fondo, lo sbaglio è solo di una parte su un milione. E quando il valore temporale è piccolo, l’errore è a sua volta piccolo. Ma il problema di un errore percentuale è che quando il valore diventa grande, anche l’errore cresce: in altri termini, quanto più a lungo il sistema Patriot rimaneva acceso, tanto più cresceva il valore del tempo e tanto più grande diventava l’errore che continuava ad accumularsi. Il giorno in cui quello Scud venne lanciato, il sistema Patriot posizionato in quell’area era acceso da circa cento ore, pari grossomodo a 360.000 secondi: più o meno un terzo di milione di secondi, e quindi l’errore era all’incirca di un terzo di secondo.

Un terzo di secondo non sembra un intervallo di tempo molto lungo, almeno finché non dovete tracciare un missile che viaggia a 6000 km/h. In un terzo di secondo, un missile Scud può percorrere più di 500 metri; ed è molto difficile tracciare e intercettare qualcosa che si trova a mezzo chilometro dal punto in cui ci aspettiamo che sia.

Così, il sistema Patriot non riuscì a fermare lo Scud, che colpì la base americana uccidendo ventotto soldati e ferendo un centinaio di altre persone.

È stata un’altra costosa lezione sull’importanza di conoscere i limiti dei numeri binari. In questo caso, però, c’è anche un’altra lezione relativa alla correzione degli sbagli. Quando il sistema era stato aggiornato per tracciare gli Scud, molto più veloci, il metodo di conversione del tempo era stato a sua volta aggiornato, ma non in modo regolare: in alcuni casi, infatti, le conversioni effettuate nel sistema usavano ancora il vecchio metodo.

Ironicamente, se l’errore nel tempo fosse stato presente in maniera costante, l’intercettazione sarebbe comunque potuta andare a buon fine: per tracciare un missile occorre tener conto in modo accurato delle differenze di tempo, così che gli effetti di un errore costante si sarebbero annullati a vicenda. Diverse parti del sistema stavano però usando livelli differenti di precisione nella loro conversione, e ciò lasciò lo spazio per una discrepanza. L’incompletezza dell’aggiornamento fu quindi il motivo per cui il sistema non riuscì a intercettare il missile in arrivo.

Ancora più deprimente è il fatto che l’esercito americano era al corrente di questo problema e il 16 febbraio 1991 aveva pubblicato una nuova versione del software per correggerlo. Tuttavia, poiché ci sarebbe voluto un po’ per distribuirla a tutti i sistemi Patriot, venne diramato un messaggio in cui si avvertivano i responsabili delle batterie di non lasciare che i sistemi rimanessero continuamente accesi per lunghi periodi di tempo. Non veniva specificato, però, l’esatto significato di «lungo periodo di tempo». Quindi, quei ventotto morti furono dovuti non solo ai problemi matematici, ma anche al modo raffazzonato in cui era stato fatto l’aggiornamento del codice e alla mancanza di un messaggio che dicesse semplicemente di riavviare i sistemi una volta al giorno.

La patch per il software arrivò a Dhahran il 26 febbraio, il giorno dopo l’attacco missilistico.

Nulla di cui preoccuparsi

In matematica, è impossibile dividere i numeri per zero. In Internet ci sono state molte discussioni infuocate su questo punto, con diverse persone che, in perfetta buona fede, sostenevano che il risultato di una divisione per zero fosse infinito. Solo che è sbagliato. La loro argomentazione dice che, se prendiamo 1/x e avviciniamo sempre di più x a zero, il valore cresce fino a diventare infinitamente grande; il che è vero solo a metà.

Ovvero solo se arriviamo dalla direzione positiva; se invece x ha in partenza un valore negativo e si avvicina allo zero da sotto, il valore di 1/x schizza verso l’infinito negativo, nella direzione completamente opposta rispetto a prima. Se un valore limite è diverso a seconda della direzione da cui ci avviciniamo, in matematica si dice che il limite è «indefinito». È impossibile dividere per zero. Il limite non esiste.

Ma che cosa succede quando i computer tentano di dividere per zero? A meno che non sia stato loro esplicitamente detto che farlo è impossibile, ingenuamente ci provano. E i risultati possono essere terrificanti.

Questa linea mostra il risultato della divisione di uno per numeri vicini a zero.

Questa linea mostra il risultato della divisione di uno per numeri vicini a zero.

I circuiti dei computer sono molto bravi a sommare e sottrarre, e i calcoli che fanno partono da lì. La moltiplicazione non è nient’altro che un’addizione ripetuta, e quindi risulta abbastanza facile da programmare. La divisione è solo un po’ più complicata: è una sottrazione che si ripete, con magari qualche resto alla fine. Così, dividere 42 per 9 significa sottrarre tutti i 9 che è possibile sottrarre, come se contassimo all’indietro per 9: 42, 33, 24, 15 e 6. Dato che ci sono voluti quattro passi, avremo che 42 ÷ 9 = 4 con il resto di 6. Oppure, possiamo convertire 6/9 in un decimale e ottenere 42 ÷ 9 = 4,6666…

Se digitiamo su un computer 42 ÷ 0, questo sistema per risolvere le divisioni va in crisi. O, meglio, non va in crisi ma continua a girare a vuoto per sempre. Possiedo una calcolatrice Casio «personal-mini» del 1975. Se le chiedo di calcolare 42 ÷ 0, lo schermo si riempie di zeri e sembra che si sia rotta, finché non premo il pulsante «mostra ulteriori cifre» e la calcolatrice rivela che sta tentando di arrivare a una risposta e che il valore di tale risposta continua a crescere vertiginosamente. La povera Casio, in pratica, sta continuando a sottrarre zero da quarantadue e tiene il conto di quante volte lo ha già fatto.

Anche le calcolatrici meccaniche più vecchie avevano questo stesso problema, ma venivano azionate tramite una manovella e c’era quindi bisogno di un uomo che continuasse a girarla, macinando – letteralmente – i numeri nell’inutile sforzo di sottrarre zeri. Per i pigri, in passato, c’erano dei calcolatori elettromeccanici dotati di un motore che faceva girare automaticamente la manovella. Online ci sono dei filmati di persone che eseguono una divisione per zero su queste macchine, con il risultato che le vediamo far girare numeri all’infinito (o finché non viene scollegata l’alimentazione).

Nei computer moderni, una semplice soluzione a questo problema consiste nell’aggiunta di una riga di codice per dire al computer di non prendersi neppure la briga di provarci. Se doveste scrivere un programma per dividere il numero a per il numero b, ecco una sorta di pseudocodice che illustra come potrebbe essere definita la funzione al fine di evitare il problema:

def dividing(a,b):

if b = 0: return ‘Error’

else: return a/b

Il modello più recente di iPhone (al momento di scrivere queste pagine) deve avere un codice quasi esattamente uguale a questo: se scrivo 42 ÷ 0, fa uscire sullo schermo la scritta «Errore» e si rifiuta di andare avanti. La calcolatrice del mio computer fa un passo in più e mi dice che «Non è un numero».3 La mia calcolatrice tascabile (Casio fx-991EX) restituisce un «Math ERROR». Io realizzo dei filmati in cui tiro fuori dalle scatole le nuove calcolatrici e le recensisco (con oltre tre milioni di visualizzazioni, in crescita). Uno dei test che eseguo sempre è quello di dividere per zero e vedere che cosa fa la calcolatrice. Nella maggior parte dei casi si comportano molto bene.

Come sempre, però, può capitare che qualche calcolatrice riesca a svicolare. E non parlo solo di calcolatrici tascabili: anche le navi da guerra della Marina americana possono sbagliare con le divisioni per zero. Nel settembre del 1997, l’incrociatore USS Yorktown rimase totalmente privo di energia perché il computer del suo sistema di controllo stava tentando di dividere per zero. La Marina lo stava usando per testare il progetto «Smart Ship»: mettere sulle navi da guerra dei computer con il sistema Windows per automatizzare una parte della gestione della nave e ridurre l’equipaggio di circa il 10 per cento. Dato che la nave rimase immobile in balia delle onde per circa due ore, l’esperimento ebbe senz’altro successo nel dare all’equipaggio un po’ di tempo libero.

Il fatto che gli esempi di errori matematici vengano in prevalenza dall’ambito militare non significa che le forze armate siano particolarmente negate per la matematica. La ragione, almeno in parte, è che l’esercito ha un forte impegno sul piano della ricerca e dello sviluppo e si trova quindi a lavorare agli estremi confini dell’innovazione, cosa che rende tendenzialmente più facili gli errori. Inoltre, i militari sono tenuti, almeno entro certi limiti, a riferire sulle cose che vanno storte. Certo, un sacco di errori matematici senza dubbio affascinanti non diventano mai di pubblico dominio, ma nelle aziende private il numero di errori che vengono completamente insabbiati è ancora più alto. E io posso parlare solo degli errori che sono stati divulgati.

Nel caso della USS Yorktown, i dettagli sono ancora un po’ confusi. Non è chiaro se fu necessario rimorchiare la nave in porto o se alla fine riuscì a riattivare l’energia al largo. Sappiamo però che la causa era stata una divisione per zero. A quanto pare, l’errore iniziò perché qualcuno aveva inserito uno zero da qualche parte in un database (che lo aveva trattato come un numero e non come una voce nulla). Quando il sistema divise un altro numero per quel valore, il computer cominciò a macinare numeri sempre più grandi come una calcolatrice da due soldi. Ciò, a sua volta, provocò un errore di overflow quando la risposta divenne più grande dello spazio che le era assegnato nella memoria del computer. Per mettere fuori combattimento una nave da guerra, c’è voluto un supergruppo di errori matematici, capitanati da una divisione per zero.

1. Ironicamente, 1/2 è quasi l’unica frazione che può essere rappresentata in modo preciso nella numerazione binaria. Nella numerazione decimale, è rappresentata da 0,5 perché cinque è la metà di dieci; analogamente, nel sistema binario è rappresentata da 0,1 perché uno è la metà di due. E se in 0,01111111… ci fossero infinite cifre, sarebbe esattamente uguale a 0,1, proprio come 0,99999… = 1. Non date retta a quelli che si lamentano online che 0,99999… ≠ 1, perché hanno tutti torto.

2. Il numero «754» non ha nessun significato particolare: l’IEEE si limita a numerare i suoi standard in sequenza, nell’ordine in cui sono stati richiesti. Quello immediatamente precedente era il 753, che trattava delle performance dei sistemi di segnalazione con composizione a impulsi («Functional Methods and Equipment for Measuring the Performance of Dial-Pulse (DP) Address Signaling Systems»), mentre quello successivo, il 755, si occupava del linguaggio dei microprocessori («Trial-use Extending High Level Language Implementations for Microprocessors»).

3. La calcolatrice di Windows 10 dice «Impossibile dividere per zero». [N.d.T.]