Java double ohne Nachkommastelle

3 Antworten

Für uns Menschen ist es kein Problem zu erkennen, ob eine Zahl Nachkommastellen hat oder nicht. Bei Ganzzahlen (int) ist die Sache klar. Bei Fließkommazahlen (float, double) muß man davon ausgehen, das irgendwo in der Mantisse der Zahl Einsen stehen.

Die Umwandlung eines Ints in ein Double ist kein Problem, weil keine Nachkommastelle betroffen ist. Dieser umgewandelte Int lässt sich auch problemlos zurückkonvertieren. Sobald der Int mit einer beliebigen Fließkommazahl Rechnungen ausführt, kann man nicht mehr beliebig aus dem Ergebnis einen Int erzeugen. Hier kommt es garantiert zu Rundungsfehlern. Das liegt einfach daren, dass praktisch immer ein paar Einsen in der Mantisse der Fließkommazahl vorkommen …

Daraus folgt, dass man sich für solche Rechnungen überlegen muß, ob Integers für die Rechnung ausreichend sind oder nicht. Natürlich kann man mit Formatierregeln und -routinen eine „3,00“ in eine „3“ umwandeln, aber da du nicht wissen kannst, welche Zahl zwischen 1 … n als Ergebnis geliefert wird, ist diese Umwandlung eher umständlich und vergleichsweise „teuer“ (bezüglich der Feststellung, dass die Nachkommastellen entfallen könnten) …

Natürlich sind in aktuellen Intel-CPUs die Fließkomma-CPUs integriert, aber erst seit etwa 20 Jahren. Zuvor mußte man eine Fließkomma-CPU entweder „emulieren“ (per Software nachbilden) oder vergleichsweise teuer dazukaufen!


TeeTier  20.06.2014, 19:41

Stimmt alles. Aus diesem Grunde habe ich auch in meiner Antwort geschrieben, dass man Gleitpunktwerte mit einem Schwellenwert, statt einer exakten Prüfung auf Null testen soll.

d <= 0.0001D || d >= 0.9999D

Meiner Meinung nach wäre "%.3f" ausreichend, aber wenn der Fragesteller eine "3" anstatt einer "3.0" oder gar "3.000" bevorzugt, soll er es von mir aus tun. Jedem das seine. :)

0
double d = 3.01234567D;

String s = String.format(((d % 1.0D) == 0.0D) ? "%.0f" : "%.4f", d);

In diesem Falle enthält s danach den String "3.0123". Wenn du hingegen d mit 3.0 initialisierst, enthält dein String "3".


TeeTier  20.06.2014, 02:28

Anmerkung: Du musst aber wissen, dass Modulo Operationen auf Double verdammt rechenintensiv sind, also geh sparsam damit um! (Zum Vergleich: "d % 1.0D" verbrät ungefähr so viel Rechenleistung wie 400 Integer-Additionen ... z.B. "x + 1" oder so) Davon merkst du bei einem schnellen Prozessor zwar nichts, wenn es nicht ständig in einer Schleife passiert, aber du solltest das im Hinterkopf behalten.

Davon abgesehen ist ein Gleitpunkt Vergleich mit exakt 0.0 keine sehr gute Idee. Hier können sich Architekturbedingt oft fiese Fehler einschleichen. Eigentlich wäre es besser, auf einen Schwellenwert zu prüfen. (z.B. "d <= 0.01D")

Naja, für deinen Fall dürfte obiges Beispiel aber dennoch ausreichend sein.

Viel Spaß! :)

0
wolfgang1956  20.06.2014, 06:59

Woher weißt du, welcher Zahlenwert vorliegt? Seine Beispielzahl ist doch nur eine von unendlich vielen Zahlen!!

0
TeeTier  20.06.2014, 19:35
@wolfgang1956

Aus diesem Grunde ist das auch nur ein Snippet und damit unvollständig. Das ist mir natürlich bewusst! :)

Ich habe darauf verzichtet eine fertige Funktion zu schreiben, da sich das jeder selbst zusammen reimen kann und ich außerdem nicht weiß, auf was der Fokus des Fragenstellers liegt. :)

0