Mentre potresti aver sentito parlare di errori di arrotondamento, potresti chiederti perché hai un errore di arrotondamento qui.
float a1 = 1.4f;
float b1 = 0.5f;
double c1 = 1.4;
double d1 = 0.5;
System.out.println(new BigDecimal(a1) + " - " + new BigDecimal(b1) + " is " +
new BigDecimal(a1).subtract(new BigDecimal(b1)) + " or as a float is " + (a1 - b1));
System.out.println(new BigDecimal(c1) + " - " + new BigDecimal(d1) + " is " +
new BigDecimal(c1).subtract(new BigDecimal(d1)) + " or as a double is " + (c1 - d1));
stampe
1.39999997615814208984375 - 0.5 is 0.89999997615814208984375 or as a float is 0.9
1.399999999999999911182158029987476766109466552734375 - 0.5 is
0.899999999999999911182158029987476766109466552734375
or as a double is 0.8999999999999999
Come si può vedere, né float
nè double
possono rappresentare questi valori esattamente, e quando il galleggiante o doppio viene stampato, un po 'l'arrotondamento avviene per nascondere questo da voi. In questo caso di float, l'arrotondamento a 7 cifre decimali produce il numero che ci si aspettava. Nel caso di double che ha 16 cifre di precisione, l'errore di arrotondamento è visibile.
Come @Eric Postpischil, indica se l'operazione float
o double
ha un errore di arrotondamento dipende interamente dai valori utilizzati. In questa situazione, era il galleggiante che sembrava essere più preciso anche se il valore rappresentato era più lontano da 0,9 rispetto al doppio valore.
In breve: se si intende utilizzare float
o double
, è necessario utilizzare una strategia di arrotondamento ragionevole. Se non puoi farlo, usa BigDecimal.
System.out.printf("a1 - b1 is %.2f%n", (a1 - b1));
System.out.printf("c1 - d1 is %.2f%n", (c1 - d1));
stampe
a1 - b1 is 0.90
c1 - d1 is 0.90
Quando si stampa un float o doppio, si assume che il valore decimale breve più vicino è quello che si vuole veramente. cioè entro 0,5 ulp.
E.g.
double d = 1.4 - 0.5;
float f = d;
System.out.println("d = " + d + " f = " + f);
stampe
d = 0.8999999999999999 f = 0.9
Simile a http://stackoverflow.com/questions/322749/retain-precision-with-doubles-in-java – tjg184
Questo può aiutare http: //epramono.blogspot .com/2005/01/double-vs-bigdecimal.html – kosa
Vedere anche http://mindprod.com/jgloss/floatingpoint.html –