Glossary
IEEE 754
Lo standard in virgola mobile alla base di ogni CPU
By Buğra SözeriPublished Updated
IEEE 754 è lo standard per l’aritmetica in virgola mobile, pubblicato per la prima volta nel 1985 e aggiornato nel 2008 e nel 2019. Definisce i formati in virgola mobile binaria e decimale, il comportamento di arrotondamento, la gestione delle eccezioni e i valori speciali (NaN, ±Infinity, −0).
Il formato standard a doppia precisione è quello usato dai Number di JavaScript, dai float di Python e dalla maggior parte degli altri tipi “numerici” nei linguaggi moderni:
- 64 bit totali
- 1 bit di segno
- 11 bit di esponente
- 52 bit di mantissa
- ~15-17 cifre decimali significative di precisione
- Intervallo approssimativo da 4.9e−324 a 1.8e+308
Il famoso esempio: 0.1 + 0.2 === 0.3 restituisce false in quasi tutti i linguaggi. Il motivo: 0.1 e 0.2 non hanno rappresentazioni binarie esatte (proprio come 1/3 non ha una rappresentazione decimale esatta). I loro valori memorizzati sono molto vicini ma non esattamente 0.1 e 0.2, e la somma amplifica il piccolo errore. Il risultato è 0.30000000000000004.
Implicazioni per i nostri strumenti: la maggior parte delle conversioni è accurata fino a ~15 cifre decimali, più che sufficiente per qualsiasi input accettato. Dove questo conta: gli importi in criptovaluta, dove i 18 decimali del Wei superano l’intervallo dei Number — lì utilizziamo BigInt per mantenere la precisione esatta.
Esempio pratico
Considera il calcolo 0.1 + 0.2 in JavaScript. Il letterale 0.1 in binario IEEE 754 è in realtà 0.10000000000000000555111512312578… (il double rappresentabile più vicino). 0.2 è 0.20000000000000001110223024625157…. Sommandoli e arrotondando al double rappresentabile più vicino si ottiene 0.30000000000000004440892098500626…, visualizzato come 0.30000000000000004. La risposta matematica vera 0.3 non è esattamente rappresentabile in binario — anche la sua rappresentazione è approssimativamente 0.299999…9989…. L’errore è nell’ultimo ulp (unità nell’ultimo posto), circa 1 su 10¹⁶. Per i numeri visibili è invisibile; per le somme di milioni di piccoli valori si accumula: sommare 0.1 cento volte in un ciclo e confrontare con 10.0 restituirà false (il risultato è 9.99999999999999822364…). Usa la sommatoria di Kahan o la sommatoria compensata quando la precisione conta nelle lunghe accumulazioni.
Altri due problemi con i valori speciali da conoscere: i numeri subnormali (valori molto piccoli vicini allo zero con precisione ridotta) scambiano l’intervallo rappresentabile per un underflow graduale, e i NaN segnalanti (sNaN) possono essere usati per intercettare la memoria non inizializzata, sebbene la maggior parte dei linguaggi mappi tutti i NaN su NaN quieti (qNaN) e non esponga mai questa distinzione al codice utente.
Quando e perché è importante
IEEE 754 conta ogni volta che il codice confronta float per uguaglianza, somma molti numeri piccoli o gestisce valori vicino ai limiti del formato. Il classico bug finanziario è calcolare “totale = totale + 0.01” in un ciclo un milione di volte e scoprire che il risultato è leggermente sbagliato quanto basta per far fallire una riconciliazione del bilancio. La soluzione è non usare mai i float per i soldi — usa BigDecimal, decimal.Decimal di Python, decimal.js di JavaScript, o memorizza gli importi come interi (centesimi invece di dollari, satoshi invece di bitcoin, wei invece di ETH). L’altro bug classico è la cancellazione catastrofica che si verifica quando si sottraggono due float quasi uguali — le cifre significative iniziali si annullano, lasciando solo il rumore nei bit inferiori. I libri di testo di analisi numerica dedicano interi capitoli ad algoritmi (ad es. la formula stabile della varianza, la sommatoria di Kahan, l’algoritmo online di Welford) che evitano questa trappola. Riferimento: Goldberg D. — What Every Computer Scientist Should Know About Floating-Point Arithmetic.
I cinque valori speciali che tutti dimenticano: IEEE 754 definisce +0 e −0 come distinti (si confrontano come uguali ma producono risultati diversi nella divisione — 1/+0 è +∞ mentre 1/−0 è −∞), +Infinity e −Infinity per l’overflow, e NaN (Not a Number) per le operazioni non definite come 0/0 o √−1. NaN è famosamente non uguale a se stesso — NaN === NaN è false — ed è così che IEEE 754 propaga gli errori nel calcolo invece di mascherarli. Il controllo Number.isNaN() esiste in ogni linguaggio moderno proprio perché il controllo di uguaglianza ovvio non funziona.
Quando hai veramente bisogno di decimale esatto — e cosa usare invece: per i soldi, non usare mai i float. BigDecimal di Java, decimal.Decimal di Python, librerie come decimal.js di JavaScript e il tipo NUMERIC di PostgreSQL implementano tutti l’aritmetica decimale esatta. Il costo è circa 10-100× più lento rispetto alle operazioni native sui float, il che va benissimo per qualsiasi sistema transazionale rivolto all’utente. Per il calcolo scientifico dove il comportamento di arrotondamento è importante, l’arrotondamento-al-pari-più-vicino (arrotondamento del banchiere) di IEEE 754 è ciò che produce somme accumulate stabili; l’arrotondamento-metà-su bias verso l’alto. La maggior parte dei linguaggi predefinisce round-half-even per questo motivo. Riferimento: IEEE 754-2019 — Aritmetica in virgola mobile.
Frequently asked questions
- Che cos’è IEEE 754?
- IEEE 754 è lo standard internazionale per l’aritmetica in virgola mobile usato in quasi tutte le CPU e nei linguaggi di programmazione. Definisce come i numeri reali vengono rappresentati in binario come campi di segno, esponente e mantissa.
- Perché 0.1 + 0.2 non è uguale a 0.3 nella maggior parte dei linguaggi?
- 0.1 e 0.2 non possono essere rappresentati esattamente in virgola mobile binaria — vengono memorizzati come il valore rappresentabile più vicino. Sommare due approssimazioni aumenta l’errore di arrotondamento, dando 0.30000000000000004 in doppia precisione IEEE 754.
- Qual è la differenza tra float (32 bit) e double (64 bit)?
- Un float a 32 bit ha circa 7 cifre decimali significative di precisione; un double a 64 bit ne ha circa 15-17. I calcoli finanziari e scientifici richiedono tipicamente la doppia precisione per evitare l’accumulo di errori di arrotondamento.
- Come gestisco l’aritmetica decimale esatta nel codice?
- Utilizza una libreria decimale (il modulo decimal di Python, BigDecimal di Java, il tipo NUMERIC di SQL) invece dei float nativi. In alternativa, lavora in centesimi interi per le valute — memorizza $1.99 come 199 e converti in una stringa decimale solo per la visualizzazione.
Related
Published May 15, 2026 · Last reviewed May 31, 2026