Java Double Wert = 0,01 ändert sich zu 0.009999999999999787 [duplizieren]

8

Ich schreibe ein grundlegendes Befehlszeilenprogramm in Java für meinen High-School-Kurs. Wir arbeiten gerade nur mit Variablen. Es wird verwendet, um die Menge an Scheinen und Münzen, welche Art auch immer, nach einem Kauf in Ihrer Änderung zu berechnen. Das ist mein Programm:

%Vor%

Es sollte alles funktionieren, aber im letzten Schritt, wenn noch $ 0,01 übrig sind, sollte die Anzahl der Pennies 1 sein, aber stattdessen ist es 0. Nachdem ich ein paar Minuten in den Code gegangen bin und den Änderungswert an die Konsole ausgegeben habe, habe ich herausgefunden, dass im letzten Schritt, wenn Änderung = 0,01, es zu 0,009999999999999787 ändert. Warum passiert das?

    
Alex 13.09.2011, 21:12
quelle

8 Antworten

7

Die Verwendung von double für Währung ist eine schlechte Idee, Warum nicht Double oder Float als Währung verwenden? . Ich empfehle, BigDecimal zu verwenden oder jede Berechnung in Cent durchzuführen.

    
Amir Raminfar 13.09.2011, 21:14
quelle
7

0.01 hat keine exakte Darstellung im Fließkommawert (und auch nicht 0.1 oder 0.2).

Sie sollten wahrscheinlich Ihre ganze Mathematik mit ganzzahligen Typen machen, die die Anzahl der Pennies darstellen.

    
Oliver Charlesworth 13.09.2011 21:14
quelle
4

doubles werden nicht intern in Dezimal, sondern binär gehalten. Ihr Speicherformat entspricht etwas wie " 100101 multipliziert mit 10000 " (ich vereinfache das, aber das ist die Grundidee). Leider gibt es keine Kombination dieser binären Werte, die genau 0,01 ergibt, was die anderen Antworten bedeuten, wenn sie sagen, dass Fließkommazahlen nicht 100% genau sind, oder dass 0,01 keine exakte Darstellung in Fließkommawerten hat Punkt.

Es gibt verschiedene Möglichkeiten, mit diesem Problem umzugehen, einige komplizierter als andere. Die beste Lösung in Ihrem Fall ist wahrscheinlich die Verwendung von int s überall und behalten Sie die Werte in Cent.

    
Jon Bright 13.09.2011 21:19
quelle
1

Wie die anderen bereits gesagt haben, verwenden Sie keine Doppel für finanzielle Berechnungen.

Dieses Papier Ссылка (Was jeder Informatiker wissen sollte Fließkomma-Arithmetik) ist ein Muss-lesen, um Fließkomma-Mathematik in Computern zu verstehen.

    
fvu 13.09.2011 21:16
quelle
0

ist ein float (double)

Sie sollten es nicht verwenden, um Geld zu berechnen ....

Ich empfehle, int-Werte zu verwenden und auf Pennys zu operieren

    
l_39217_l 13.09.2011 21:15
quelle
0

Dies ist ein Problem, das viele Male aufgetreten ist. Die Quintessenz ist, dass auf einem Computer, der einen binären Fließkommawert verwendet (was Java benötigt), nur Bruchteile, in denen der Nenner eine Potenz von 2 ist, genau dargestellt werden können.

Das gleiche Problem tritt in Dezimal auf. 1/3 zum Beispiel wird zu 0,3333333 ..., weil 3 kein Faktor 10 ist (die Basis, die wir dezimal verwenden). Ebenso 1/17, 1/19 usw.

Im binären Gleitkomma tritt das gleiche Grundproblem auf. Der Hauptunterschied ist, dass in Dezimal, da 5 ein Faktor von 10 ist, 1/5 genau dargestellt werden kann (und auch Vielfache von 1/5). Da 5 kein Faktor 2 ist, kann 1/5 nicht im binären Fließkomma genau dargestellt werden.

Entgegen der landläufigen Meinung können jedoch einige Fraktionen genau dargestellt werden - insbesondere solche Brüche, deren Nenner mit nur 2 als Primfaktor (zB 1/8 oder 1/256) dargestellt werden können genau).

    
Jerry Coffin 13.09.2011 21:18
quelle
0

Ich bin sicher, dass Sie wissen, dass die Dezimaldarstellungen einiger Bruchteile enden (z. B. .01), während einige nicht (z. B. 2/3 = .66666 ...). Die Sache ist, dass die Brüche die Änderungen abhängig davon abbrechen, in welcher Basis du bist; Insbesondere endet .01 nicht im Binärformat, also kann double, obwohl es sehr genau ist, nicht genau 0,01 darstellen. Wie andere sagten, ist die Verwendung von BigDecimal- oder Festkomma-Ganzzahlberechnungen (Konvertieren von allem in Cents) wahrscheinlich am besten für Währungen; um mehr über Fließkomma zu lernen, könntest du bei Der Fließkomma-Guide - Was jeder Programmierer über Fließkomma-Arithmetik wissen sollte .

    
Prodicus 13.09.2011 21:22
quelle
0

Fließkommazahlen sind niemals 100% genau (nicht ganz richtig, siehe Kommentare unten). Sie sollten sie niemals direkt vergleichen. Auch ganzzahlige Rundung. Der beste Weg, dies zu tun, wäre wahrscheinlich, es in Cent zu tun und später zu Dollars zu konvertieren (1 Dollar == 100 Cent). Durch die Umwandlung in eine Ganzzahl verlieren Sie die Genauigkeit.

    
joshx0rfz 13.09.2011 21:15
quelle

Tags und Links