# Decimalformat, Fehler beim runden?



## Tom4712 (12. Jun 2007)

Hallo,

innerhalb einer Anwendung wollt ich Decimalformat zum runden von Kommazahlen verwenden. Dabei ist mir aufgefallen das hierbei ein Fehler auftritt. Wenn beim Runden eine 5 vorliegt wird einmal auf und einmal abgerundet. Ich habe eine einfache Klasse geschrieben um das zu testen:


```
public class RundenTest {

	public static void main(String[] args)
	{			
		DecimalFormat format = new DecimalFormat("0.000");
		
		
		double d = 12348.4215; 
		System.out.println(format.format(d));
//	Ausgabe --> 12348,422 --> Richtig

		d = 12348.4225;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,422 --> Falsch
				
		d = 12348.4235;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,424 --> Richtig
		
		d = 12348.4245;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,424 --> Falsch
		
		d = 12348.4255;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,426 --> Richtig
		
		d = 12348.4265;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,426 --> Falsch
		
		d = 12348.4275;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,428 --> Richtig
		
		d = 12348.4285;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,428 --> Falsch
		
		d = 12348.4295;
		System.out.println(format.format(d));
//	Ausgabe --> 12348,430 --> Richtig
	}				
	
}
```


Warum passiert dieser Fehler?


----------



## kleiner_held (12. Jun 2007)

Dir ist schon bekannt, dass im double Zahlen wie 12348.4295 nicht exakt abgebildet werden?


----------



## Tom4712 (12. Jun 2007)

Ja, es ist aber doch schon auffällig, dass immer jeder zweite Wert falsch gerundet wird. Aussdem ist das Ergebniss immer gleich. Wenn es daran liegen würde dass die Werte nicht exakt abgebildet werden, würde der Fehler doch immer an anderen Stellen auftauchen. 
Oder sehe ich das falsch?


----------



## Wildcard (12. Jun 2007)

Tom4712 hat gesagt.:
			
		

> Oder sehe ich das falsch?


Ja, das siehst du falsch.
http://docs.sun.com/source/806-3568/ncg_goldberg.html


----------



## SlaterB (12. Jun 2007)

was soll denn der 100 Seiten-Link? 

der Test zeigt doch eindeutig, dass da kein Zufall vorliegt,
mag vielleicht vom PC abhängen (ist es bei jemanden anders?), aber dann eindeutig nach double-Wert


----------



## Wildcard (12. Jun 2007)

SlaterB hat gesagt.:
			
		

> was soll denn der 100 Seiten-Link?


Das ist einfach Basis Wissen, daher auch der Titel
What *Every* Computer Scientist Should Know About Floating-Point Arithmetic


----------



## Tom4712 (12. Jun 2007)

Liegt das Problem also daran, dass die nach der Zuweisung von 12348.4295 and gar nicht 12348.4295 in d steht sondern ein anderer Wert?

Wie kann ich denn stattdessen richtig runden?


----------



## SlaterB (12. Jun 2007)

verlustfreies Rechnen und damit auch runden ist z.B. mit BigDecimal möglich

wenns unbedingt double sein wohl, dann helfen nur eigens gewählte Grenzen:
if (x-floor(x) > 0.4999999)
und ähnliches


----------



## Wildcard (12. Jun 2007)

SlaterB hat gesagt.:
			
		

> verlustfreies Rechnen und damit auch runden ist z.B. mit BigDecimal möglich


Braucht man aber nur für sehr kritische Anwendungen bei denen absolute Genauigkeit gefragt ist.
Da Tom4712 sowieso rundet halte ich BigDecimal für unnötig.


----------

