Copied to Clipboard
Non è un "bug di JavaScript". È un effetto della rappresentazione numerica più comune: i floating point (IEEE 754).
Perché succede: base 10 vs base 2
Noi ragioniamo in base 10 (decimale). I computer, invece, memorizzano i numeri in base 2 (binario). Alcuni decimali "semplici" per noi—come 0.1 o 0.2—in binario non hanno una rappresentazione finita. Quindi vengono salvati come approssimazioni.
Sommi due approssimazioni e ottieni un’altra approssimazione: nella maggior parte delle UI non cambia nulla, ma in ambito finanziario (grandi volumi, riconciliazioni, audit) quei residui diventano costi, contestazioni o vulnerabilità.
La regola d’oro nei sistemi di pagamento: niente floating point per la valuta
Per questo i sistemi moderni seri non memorizzano denaro come decimali floating.
L’approccio tipico è:
- salvare importi come interi nella unità minima (es. centesimi);
- fare tutte le operazioni (somma/sottrazione) su interi;
- convertire in decimale solo in fase di visualizzazione.
Esempio: invece di 10.23, memorizzi 1023.
Questo elimina la classe di errori "0.30000000000000004" e riduce drasticamente le discrepanze da arrotondamento.
Implicazioni pratiche per chi fa frontend
Anche se la contabilità "vera" vive sul backend, il frontend può introdurre divergenze che poi diventano bug difficili da diagnosticare. Alcune pratiche pragmatiche:
-
Non sommare prezzi in
Number se devi ottenere totali affidabili (carrello, tasse, sconti, rate).
-
Trasporta importi come interi (es.
amountCents) nelle API e nei modelli di stato.
-
Definisci una strategia di arrotondamento unica (half-up, half-even, ecc.) e applicala in un solo punto del flusso, non "a ogni passaggio".
-
Formatta per l’utente, non per il calcolo: usa
Intl.NumberFormat per mostrare, non per computare.
- Se servono grandi numeri o regole complesse (tassi, conversioni, interessi), valuta librerie/approcci dedicati o tipi numerici appropriati (in JS moderno anche
BigInt, dove applicabile), ma senza mescolare casualmente rappresentazioni diverse.
Sintesi: la precisione non è un dettaglio, è una feature
Quando lavori con prezzi e pagamenti, l’obiettivo non è "avere un numero vicino": è avere sempre lo stesso numero tra UI, backend, sistemi esterni e riconciliazioni.
La lezione è semplice e pratica: i floating point sono ottimi per molte cose, ma il denaro non è una di quelle. Nel momento in cui rappresenti importi come interi (centesimi) e tratti l’arrotondamento come una regola di business, smetti di inseguire fantasmi come 0.30000000000000004 e costruisci un sistema molto più robusto, verificabile e difficile da sfruttare.
Articolo originale: https://frontendfacile.it/blog/perche-i-computer-non-sanno-contare-i-soldi-e-cosa-fare-nel-frontend