# Fließkomma (double) richtig runden



## The_S (10. Sep 2005)

Hi,

leider hat ja jede Programmiersprache (wie u. a. auch hier in einigen Threads festgestellt wurde) ihre Probleme mit Fließkommazahlen und es kommt öffters vor, dass z. B. bei der Multiplikation von 10 und 2 nicht wie zu erwarten 20 rauskommt, sondern entweder 20.000000000000002 oder 19.999999999999999998 (die Nullen bzw. Neunen sind jetzt net zwingend in der Anzahl richtig). Das kann man ja ganz net umgehen, indem man schön rundet. Nur was machen, wenn man mit extrem kleinen Zahlen arbeiten muss? Z. B. 1.2E-16? Wenn man da dann auch rundet, bekommt man als Ergebnis logischerweiße 0.0 raus. Und genau das ist hier der Fall bei mir. Hat jemand eine Idee, wie man das umgehen kann?


----------



## 8ull23y3 (10. Sep 2005)

Vielleicht hilft das http://java.sun.com/j2se/1.5.0/docs/api/java/text/DecimalFormat.html


----------



## The_S (10. Sep 2005)

An was genau hast du dabei gedacht? Z. B. so


```
DecimalFormat df = new DecimalFormat("#,##0.0#########"); 
df.format(wert);
```

Hab ich es schon ausprobiert, aber ich weiß ja nicht wie viele Nachkommastellen ich habe und dann bekomme ich am Ende wieder 0 raus  . Oder hattest du da jetzt was anderes im Auge?


----------



## Solour (11. Sep 2005)

bin da def. kein experte aber maybe mit 10^20 multiplizioeren und dann runden?


----------



## The_S (11. Sep 2005)

Das prob is halt, dass des Ding ewig viele Nachkommastellen haben kann. Mir gehts jetzt auch gar net speziell um den Fehler, weil 0,0000000000000002 unterschied schläft net sonderlich ins gewicht, sondern eher, wenn ich z. B. 100,0 mit 200000000,0 multiplizier und dem User als Ergebnis ne ewiglange Kommazahl präsentier, wird der mein Programm net grad sehr vertrauenswürdig halten ... Hab mir mal folgenden Code überlegt, aber hatte noch keine Zeit zum testen (is auch net gerade der schönste  )


```
double doRound(double wert) { 
		 
		String temp = String.valueOf(wert); 
		String exp = null; 
		NumberFormat nf = NumberFormat.getInstance(); 
		int tempI = temp.indexOf("E"); 
		if (tempI != -1 && tempI - temp.indexOf(".") > 10) { 
			exp = temp.substring(tempI, temp.length());
			if ((temp.substring(tempI - 10, tempI).equals("0000000002") && !temp.startsWith("0")) || 
				temp.substring(tempI - 10, tempI - 1).equals("9999999998")) {  
				temp = temp.substring(0, tempI - 2); 
				nf.setMaximumFractionDigits(temp.substring(temp.indexOf(".") + 1, temp.length()).length()); 
				temp = nf.format(Double.parseDouble(temp)).replaceAll("\\.", ""); 
				temp = temp.replaceAll(",", "\\.") + exp; 
			}
			else if ((Integer.parseInt(exp.substring(2, 4)) >= 19 || exp.length() >= 5) && exp.charAt(1) == '-') {
				temp = "0";
			}
		} 
		else if (temp.endsWith("0000000002") || temp.endsWith("9999999998")) { 
			temp = temp.substring(0, temp.length() - 1); 
			nf.setMaximumFractionDigits(temp.substring(temp.indexOf(".") + 1, temp.length()).length()); 
			temp = nf.format(Double.parseDouble(temp)).replaceAll("\\.", ""); 
			temp = temp.replaceAll(",", "\\."); 
		} 
		return Double.parseDouble(temp); 
	}
```

[edit] Code aktualisiert


----------



## The_S (13. Sep 2005)

Habs jetzt mal mit BigDecimal probiert, da gibts bis jetzt keine Probleme! Hoff das bleibt auch so!


----------



## SnooP (13. Sep 2005)

Schade das wollt ich grad vorschlagen  - hab damit auch schon gearbeitet im 1000fachen Nachkommabereich... einziges Manko ist die Performance - aber die ist numal schlechter, wenn man nicht mit im Prozessor vorhandenen Datentypen rumhantiert


----------



## The_S (13. Sep 2005)

Ja, nur leider habe ich jetzt dieses Problem, welches vorher nicht auftrat:

http://www.java-forum.org/de/viewtopic.php?t=22289&highlight=


----------

