Perché 0.1 + 0.2 fa 0.30000000000000004

Perché il floating point binario fa risultare 0.1 più 0.2 come 0.30000000000000004, e come questa calcolatrice lo arrotonda di nuovo a un pulito 0.3.

Digita 0.1 + 0.2 in quasi qualsiasi calcolatrice che lavora in floating point binario e il risultato grezzo è 0.30000000000000004, non 0.3. Anche questa calcolatrice produce internamente lo stesso valore, poi lo arrotonda per la visualizzazione, quindi vedi 0.3. Il colpevole è un disallineamento tra basi numeriche: gli esseri umani scrivono i numeri in base 10, i computer li memorizzano in base 2, e 0.1 non esiste in modo esatto in base 2.

Punti chiave

  • 0.1 + 0.2 fa 0.30000000000000004 in floating point binario, in ogni linguaggio.
  • 0.1 in binario è uno schema periodico, 0.0001100110011….
  • Questa calcolatrice arrotonda i risultati a 12 cifre significative, quindi mostra 0.3, non il double grezzo.
  • Il valore memorizzato per 0.1 risulta essere 0.10000000000000000555111512312578….

Da dove vengono le cifre in più

Sai già che alcune frazioni non stanno bene in base 10. Un terzo fa 0.333…, periodico all’infinito, perché 3 non è un fattore di 10. I computer memorizzano i numeri in base 2, dove le uniche frazioni “pulite” hanno potenze di due al denominatore: mezzi, quarti, ottavi. Un decimo non è in quella lista. In binario, 0.1 è 0.0001100110011…, periodico all’infinito, esattamente come un terzo è periodico in decimale.

Un numero a doppia precisione ha 53 bit per le cifre, quindi l’espansione binaria infinita viene troncata. Il valore memorizzato quando digiti 0.1 è 0.1000000000000000055511151231257827021181583404541015625. È vicino a 0.1 ma non uguale. Sommando due di questi valori leggermente scostati gli errori non si annullano; si sommano tra loro, e il totale finisce un passo oltre 0.3. Da qui 0.30000000000000004. Questo è lo standard IEEE 754, implementato praticamente da ogni processore e linguaggio, quindi lo stesso risultato compare in JavaScript, Python, C ed Excel.

Cosa fa questa calcolatrice al riguardo

Il contratto operativo di questo sito è spiegato nella guida al floating point: ogni risultato viene arrotondato a 12 cifre significative prima di essere mostrato. Un double porta con sé circa 15-17 cifre affidabili, quindi arrotondare a 12 mantiene ogni cifra di cui ci si può fidare e scarta le ultime, che è esattamente dove si annida il rumore accumulato.

Esempio svolto 1: provalo tu stesso. Sulla calcolatrice principale, digita 0.1+0.2. Il display restituisce 0.3. Il double sottostante è 0.30000000000000004, ma la regola di visualizzazione lo nasconde. Ripeti lo stesso trucco al contrario con 0.3-0.2: il risultato grezzo è 0.09999999999999998, e il display mostra 0.1. Anche la moltiplicazione lo fa: 1.1*3 contiene internamente 3.3000000000000003 e mostra 3.3.

Quando la risposta non può davvero essere fissata con precisione, la calcolatrice non finge. Digita 1/3 e mostra 0.333333333333, dodici tre e poi si ferma. La guida alle cifre significative spiega esattamente come funzionano quell’arrotondamento e quei limiti di visualizzazione.

Quando la differenza conta

Per l’aritmetica quotidiana, i compiti a casa e le stime ingegneristiche, 12 cifre affidabili sono molta più precisione di quanta ne giustifichi qualsiasi misurazione. La differenza conta in tre situazioni più circoscritte, tutte descritte nella guida al floating point:

  • Denaro. Non memorizzare la valuta come numero in floating point. Centesimi come numeri interi sono la via sicura, e i totali che accumulano piccoli errori sono una classe nota di bug contabili.
  • Controlli di uguaglianza nel codice. Verificare se due float calcolati sono uguali non è affidabile; confrontali invece con una piccola tolleranza.
  • Lunghe catene di operazioni. Gli errori si accumulano, e sottrarre due numeri quasi uguali fa perdere la maggior parte della precisione.

Esempio svolto 2: frazioni esatte. Quando ti serve una frazione esatta al 100%, la calcolatrice di frazioni mantiene numeratori e denominatori come numeri interi e non arrotonda mai. Digita 1/3 + 1/3 + 1/3 lì e restituisce esattamente 1. Fai la stessa somma con i decimali visualizzati, 0.333333333333 + 0.333333333333 + 0.333333333333, e il risultato è 0.999999999999. Stessa idea, mondi diversi.

Esempio svolto 3: radici e quadrati. sqrt(2)^2 è un classico inciampo. Logicamente, la radice quadrata di 2 elevata al quadrato fa 2. Sulla calcolatrice il risultato grezzo è 2.0000000000000004, arrotondato per la visualizzazione a 2. Quando ti serve il valore esatto, mantieni la forma con la radice e valuta una sola volta alla fine, argomento trattato dal riferimento delle funzioni della calcolatrice alla voce del tasto √.

C’è anche un limite intero da conoscere. Sotto 2^53 − 1 = 9,007,199,254,740,991, ogni numero intero è rappresentabile in modo esatto e la calcolatrice ne stampa tutte le cifre. Sopra quella soglia, valori come 19! passano alla notazione scientifica invece di rivendicare una precisione che non esiste.

Domande frequenti

0.1 più 0.2 fa davvero 0.3 oppure no?

Nell’aritmetica decimale esatta sì. Nel floating point binario, il risultato memorizzato è 0.30000000000000004. Questa calcolatrice restituisce internamente lo stesso valore e lo arrotonda a 12 cifre significative per la visualizzazione, quindi vedi 0.3.

È un bug della calcolatrice?

No. È lo standard IEEE 754, implementato da praticamente ogni processore e linguaggio mainstream. I programmi e le calcolatrici che sembrano evitare il problema lo stanno semplicemente nascondendo con l’arrotondamento in fase di visualizzazione, esattamente come fa questa.

Come posso ottenere una risposta esatta?

Usa la calcolatrice di frazioni per l’aritmetica razionale, che non arrotonda mai, oppure mantieni forme simboliche come sqrt(2) e pi nell’espressione fino all’ultimo passaggio.

Perché 1 diviso 3 mostra solo dodici tre?

Perché un terzo non ha una rappresentazione esatta in nessuna delle due basi. La calcolatrice mostra dodici cifre affidabili e si ferma, invece di fingere che il valore termini.