Runden klappt nicht

herrhans

Neues Mitglied
Hallo,

ich fange gerade mit Java in Eclipse an und habe Google bereits nach einer Lösung bemüht. Dabei bin ich auf folgende Möglichkeit zum Runden auf 2 Dezimalstellen gekommen:
Java:
x=Math.round(Variable*100)/100

Mich würde nun interessieren, wieso hier verschiedene Ergenisse rauskommen:

Java:
Math.round(x*100)/100.0;
Ergebnis: 36.8
Java:
Math.round(x*100)*0.01;
Ergebnis: 36.800000000000004

Anscheinend ist ja 100*x = 3680 und es erscheint mir logisch, dass deswegen im ersten Fall die 0 weggelassen wird und ich über eine Formatierung die auch anzeigen lassen könnte, aber woher kommt im zweiten Fall die 4? Ich dachte, dass durch das Math.round diese vorher "abgehackt" wird.

Gruß
Hans
 
Das kommt durch die ungenauigkeit der gleitkommazahlen.
Google mal nach "ungenauigkeit gleitkommazahlen", da solltest du gut was finden dazu.
 
Java wurde so auf Geschwindigkeit getrimmt, dass man bei normalen Anwendungen kleine Fehler in z.B. der Gleitkommarechnung zulässt. Falls man es benötigen sollte, kann man immer noch genau rechnen allerdings, ist es in den meisten Fällen mit einem kleinen unbedeutenen Fehler viel schneller.
 
Mich würde nun interessieren, wieso hier verschiedene Ergenisse rauskommen:
Dass liegt daran, weil Dezimalstellen im Computer nicht exakt dargestellt werden können. Im binären Zahlenbereich sind einige "normale" Dezimalbrüche unendlich. Da Computer aber immer mit begrenzten Zahlen arbeiten kommt es zu "digitalisierungsfehlern".

Deswegen eignen sich Fließkommazahlen übrigens nicht für Rechnungen mit Geld...

bye
TT
 
Das hat übrigens nicht mit Geschwindigkeitsoptimierungen in Java zu tun, sondern fängt schon hardwaremäßig bei der Fließkommaeinheit an.
 
sehr gut umformuliert😉, ist nämlich eine klassische Aufgabenstellung um die Speicherung von Daten (als Binärcode) und deren Konsequenzen zu zeigen...
Hat was damit zu tun, das man im Binärcode nur 2^n-Potenzen darstellen kann
 
Wenn du eine Ganzzahl benötigst, dann musst du das Ergebnis in eine umgießen. Dann brauchts du auch die mathematische Funktion nicht und kannst (int)(meineZahl+0.5) schreiben.
 
sehr gut umformuliert😉, ist nämlich eine klassische Aufgabenstellung um die Speicherung von Daten (als Binärcode) und deren Konsequenzen zu zeigen...
Hat was damit zu tun, das man im Binärcode nur 2^n-Potenzen darstellen kann

ja, das ist natürlich richtig, aber wenn man mal ganz spitzfindig sein will:
eigentlich müsste dann ja beide Male 36.800000000000004 "rauskommen", aber da spielt wohl auch noch die Frage der Formatierung/Darstellung eine Rolle, oder?!

viele Grüße
Olli
 
schöner klassenname ... wusste gar nicht das es sowas gibt =D

@Olli_M
nein ... nicht unbedingt ... denn das problem ist weniger die 3680.0d durch 100.0d zu teilen ... sondern mit 0.01d zu multiplizieren ... denn 100.0d kann glaube ich exakt ohne fehler dargestellt werden ... 0.01d hingegen aber nur noch näherungsweise mit glaube 0.01000000001d oder sowas ... und darum kommt bei der multiplikation was falsches raus ... und bei der division was exaktes ... weil nämlich nicht das ergebnis das problem ist sondern der zweite rechen-operand der in einem fall nicht 100% exakt dargestellt werden kann ...

genau das gleiche problem gilt wenn man z.b. sowas hat

for(double counter=0.0d; counter!=1.0d; counter+=0.1d)

wäre ein endlos-loop ... da counter nie genau 1.0d erreichen würde da 0.1d nicht 100% exakt dargestellt werden kann ...
 

Neue Themen


Zurück
Oben