Java rechnet falsch!
lehmann21
- java
1 Slyh0 lehmann212 Slyh0 Biesterfeld
0 lehmann21
System.out.println(1.1 * 100);
=> 110.00000000000001
Bei Nachforschungen über dieses unerwartete Ergebnis habe ich folgendes Dokument gefunden:
http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf
und siehe da:
Java implementiert IEE754 nicht korrekt bzw. vollständig und verrechnet sich dadurch bei Gleitkommazahlberechnungen.
BUH!
Hallo,
System.out.println(1.1 * 100);
=> 110.00000000000001
Das wird dir vermutlich bei jeder Sprache/Library, die IEE754 verwendet,
passieren. Eine Erklärung, die ich auf die Schnelle für genau dein Zahl-
Beispiel gefunden habe, gibt es z.B. in der Python-Doku:
http://www.python.org/doc/2.4.4/whatsnew/node9.html
Java implementiert IEE754 nicht korrekt bzw. vollständig und verrechnet sich dadurch bei Gleitkommazahlberechnungen.
Ich habe den Artikel nicht gelesen. Möglich, daß Java das nicht tut.
(Ich halte es persönlich für eher unwahrscheinlich, aber ok.) Dein
Beispiel hat jedenfalls damit nichts zu tun.
BUH!
...
Gruß
Slyh
Java implementiert IEE754 nicht korrekt bzw. vollständig und verrechnet sich dadurch bei Gleitkommazahlberechnungen.
Ich habe den Artikel nicht gelesen. Möglich, daß Java das nicht tut.
(Ich halte es persönlich für eher unwahrscheinlich, aber ok.) Dein
Beispiel hat jedenfalls damit nichts zu tun.
Mein Beispiel hat vielleicht doch damit zutun:
Komischerweise ist nämlich die Darstellung von 1,1; 1,1 * 10 und 1,1 * 1000 korrekt - der Fehler hängt also nicht (nur) von der Darstellung bestimmter Zahlen sondern von den ausgeführten arithmetischen Operation ab. Um solche Ungenauigkeiten zu verhindern, sieht IEEE754 eine Rundung der Werte vor. Schlampt hier Java eventuell genauso, wie bei der Typumwandlung von Gleitkommazahlen zu Ganzzahlen (Nachkommastellen werden einfach abgeschnitten)?
Hallo,
Mein Beispiel hat vielleicht doch damit zutun:
Komischerweise ist nämlich die Darstellung von 1,1; 1,1 * 10 und 1,1 * 1000 korrekt - der Fehler hängt also nicht (nur) von der Darstellung bestimmter Zahlen sondern von den ausgeführten arithmetischen Operation ab.
Wie dem von mir verlinkten Dokument zu entnehmen ist, kann die Ausgabe(!)
tatsächlich "korrekt" sein. Die interne Repräsentation von 1.1 bleibt
aber nunmal die gleiche.
Um solche Ungenauigkeiten zu verhindern, sieht IEEE754 eine Rundung der Werte vor. Schlampt hier Java eventuell genauso, wie bei der Typumwandlung von Gleitkommazahlen zu Ganzzahlen (Nachkommastellen werden einfach abgeschnitten)?
Letzteres ist eine Konvention. Das ist keine Schlamperei, sondern
Absicht und in jeder mir bekannten Sprache so umgesetzt. (Das hat
sicherlich auch damit zu tun, daß aus einem 5/2 bei Ganzzahlrechnung
eben auch nicht 3, sondern 2 wird. Und das ist seit den ersten
Prozessoren so. Wieso sollte es bei Casts anders sein?)
Gruß
Slyh
Hej,
Schlampt hier Java eventuell genauso, wie bei der Typumwandlung von Gleitkommazahlen zu Ganzzahlen (Nachkommastellen werden einfach abgeschnitten)?
Wie sollte denn deines Erachtens ein Cast von z.B. double auf int sonst vorgenommen werden? Das was du Schlamperei nennst wird weitläufig als "round-towards-zero" bezeichnet, entspricht AFAIR der IEE_E_754 und ist in der Java-Spec so festgelegt.
Beste Grüße
Biesterfeld
Ich habe den Artikel nicht gelesen. Möglich, daß Java das nicht tut.
(Ich halte es persönlich für eher unwahrscheinlich, aber ok.) Dein
Beispiel hat jedenfalls damit nichts zu tun.
ok, überzeugt: mit C/C++ kommt das selbe raus:
printf("%.17g\n", 1.1 * 100);
=> 110.00000000000001