Perché non utilizzare double per il denaro
Problemi di precisione in virgola mobile
Perché non utilizzare double per il denaro è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
Un valore predefinito pericoloso
È naturale pensare di memorizzare i prezzi in un double. Purtroppo, double non è in grado di rappresentare esattamente la maggior parte delle frazioni decimali, causando piccoli errori che compromettono i calcoli finanziari.
La sorpresa classica
Se somma 0.1 e 0.2 con double, non ottiene 0.3. Ottiene un valore con un piccolo errore di arrotondamento.
public class Main {
public static void main(String[] args) {
double result = 0.1 + 0.2;
System.out.println(result);
}
}Perché succede
I computer memorizzano double in formato binario. Proprio come un terzo non può essere scritto esattamente in formato decimale, molti numeri decimali come 0.1 non possono essere scritti esattamente in formato binario.
Viene memorizzata l'approssimazione binaria più vicina e l'errore si accumula.
Gli errori si accumulano
Un singolo errore molto piccolo può sembrare innocuo, ma in un ciclo che elabora migliaia di transazioni le differenze si accumulano fino a produrre errori visibili.
public class Main {
public static void main(String[] args) {
double total = 0.0;
for (int i = 0; i < 10; i++) {
total += 0.1;
}
System.out.println(total);
}
}Confronto di uguaglianza fallito
A causa degli errori di arrotondamento, confrontare valori double calcolati con == spesso non dà il risultato atteso quando si pensa che siano uguali.
public class Main {
public static void main(String[] args) {
double a = 0.1 + 0.2;
double b = 0.3;
System.out.println(a == b);
}
}Il denaro richiede precisione
In ambito finanziario, un errore anche di una frazione di centesimo è inaccettabile. I revisori si aspettano che i totali coincidano al centesimo.
Per questo il denaro non dovrebbe mai essere memorizzato in un tipo a virgola mobile.
La soluzione: BigDecimal
Java fornisce BigDecimal, una classe che memorizza i numeri decimali in modo esatto. Tiene separati il valore non scalato e la scala, quindi 0.1 significa davvero 0.1.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b));
}
}Usi sempre il costruttore String
Crei un BigDecimal da una String, non da un double. Passare un double trasferisce l'errore binario nel BigDecimal.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal fromDouble = new BigDecimal(0.1);
BigDecimal fromString = new BigDecimal("0.1");
System.out.println(fromDouble);
System.out.println(fromString);
}
}Oppure usi valueOf
BigDecimal.valueOf è una scorciatoia sicura. Converte il double utilizzando la sua forma canonica in stringa, evitando l'errore binario originale.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal price = BigDecimal.valueOf(19.99);
System.out.println(price);
}
}Memorizzare il denaro in centesimi
Un'alternativa per i casi semplici consiste nel memorizzare il denaro come numero intero di centesimi, utilizzando long. In questo modo 19.99 dollari diventano 1999 centesimi e tutti i calcoli sono esatti perché eseguiti su interi.
public class Main {
public static void main(String[] args) {
long cents = 1999;
long total = cents * 3;
System.out.println(total + " cents");
}
}Il punto essenziale
Utilizzi float e double per attività scientifiche e grafiche, dove piccoli errori sono accettabili. Per il denaro e per qualsiasi valore che debba essere esatto, utilizzi BigDecimal o un numero intero di centesimi.
Verifica rapida
Verifichi la sua comprensione della precisione dei numeri a virgola mobile.
Riepilogo
Ha imparato perché double non è adatto al denaro:
- La virgola mobile binaria non è in grado di memorizzare esattamente molti numeri decimali
- Errori come
0.1 + 0.2diverso da 0.3 si accumulano - Utilizzi
BigDecimalper l'aritmetica decimale esatta - Lo crei da una String o con
valueOf, mai da un double non elaborato - Memorizzare i centesimi come interi è un'altra opzione esatta
Domande Frequenti
La lezione «Perché non utilizzare double per il denaro» è gratuita?
Sì — il testo completo di «Perché non utilizzare double per il denaro» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «Perché non utilizzare double per il denaro»?
Problemi di precisione in virgola mobile Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Perché non utilizzare double per il denaro»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Perché non utilizzare double per il denaro
- Utilizzare BigDecimal
- Arrotondamento e scala
- BigInteger per numeri enormi