# Ausgabe von Werten des Typs double



## tester01 (11. Mrz 2012)

Hallo,

ich arbeite mich gerade durch ein Java Tutorial. Folgender Code wurde benutzt:


```
public class Aufgabe5 {
	
	public static void main ( String[] args ){
	    
		double x,ergebnis;
		for (x=0.0;x<10.0;x=x+0.1) {
		
			ergebnis = (3.0*x*x)-(8.0*x)+4.0;
			System.out.println("x: " + x +" Ergebnis: " + ergebnis);
		
		}		
	 }
}
```

Die Ausgabe ist folgende:

x: 0.0 Ergebnis: 4.0
x: 0.1 Ergebnis: 3.23
x: 0.2 Ergebnis: 2.52
x: 0.30000000000000004 Ergebnis: 1.8699999999999997
x: 0.4 Ergebnis: 1.2799999999999998
x: 0.5 Ergebnis: 0.75
x: 0.6 Ergebnis: 0.28000000000000025
x: 0.7 Ergebnis: -0.1299999999999999
x: 0.7999999999999999 Ergebnis: -0.47999999999999954

Warum wird aus x=0.3 gleich = 0.30000000000000004 ?

Oder habe ich hier noch einen Denkfehler ?

Grüße,

Thomas


----------



## Gast2 (11. Mrz 2012)

Fließkommazahlen können intern nur mit ner endlichen Genauigkeit gespeichert werden, deswegen kann es bei float/double zu diesen "ungenauigkeiten" kommen.

Für die Ausgabe kannst du dann z.b. mit dem NumberFormat runden.


----------



## irgendjemand (11. Mrz 2012)

alternativ java.math.BigDecimal ...

[OT]*hatten wir nicht mal diskusion über die angebliche sinnlosigkeit dieser klasse ? hier hätten wir mal ein beispiel dafür das diese klasse durchaus wichtig sein kann*[/OT]


----------



## faetzminator (11. Mrz 2012)

irgendjemand hat gesagt.:


> alternativ java.math.BigDecimal ...
> 
> [OT]*hatten wir nicht mal diskusion über die angebliche sinnlosigkeit dieser klasse ? hier hätten wir mal ein beispiel dafür das diese klasse durchaus wichtig sein kann*[/OT]



Naja, BigDecimal ist IMHO eher für zu grosse Zahlen gedacht.
Ich würd im Fall von tester01 eher die formatierte Ausgabe ([c]printf()[/c]) verwenden. Oder alternativ kann man natürlich noch auf eine gewisse Stelle runden. Dazu einfach [c]* Math.pow(10, n)[/c], dann [c]Math.round()[c] und wieder durch die multiplizierte Zahl rechnen (gibt das Ergebnis für [c]n[/c] Nachkommastellen).


----------



## tester01 (11. Mrz 2012)

Hallo,

vielen Dank für eure Tips. Ich werde die formatierte Ausgabe versuchen.

Bei der Berechnung eines Ergebnisses verstehe ich die "Rundungsfehler" bzw. "Ungenauigkeiten".

Bei einer expliziten Zuweisung eines Wertes noch immer nicht wirklich. Wenn der Wert 0.3 zugewiesen wird sollten die nachfolgenden Stellen mit 0 aufgefüllt werden?

Oder man initialisiert immer mit der kompletten Genauigkeit, und schreibt bei double einfach die 17 Nachkommastellen:

x=0.30000000000000000



Grüße,

Thomas


----------



## javapower (11. Mrz 2012)

Wenn es nur um die Ausgabe geht, versuche einmal folgendes:


```
System.out.printf("x: %.1f  Ergebnis: %.1f\n" , x, ergebnis);
```


----------



## irgendjemand (12. Mrz 2012)

faetzminator hat gesagt.:


> Naja, BigDecimal ist IMHO eher für zu grosse Zahlen gedacht.
> Ich würd im Fall von tester01 eher die formatierte Ausgabe ([c]printf()[/c]) verwenden. Oder alternativ kann man natürlich noch auf eine gewisse Stelle runden. Dazu einfach [c]* Math.pow(10, n)[/c], dann [c]Math.round()[c] und wieder durch die multiplizierte Zahl rechnen (gibt das Ergebnis für [c]n[/c] Nachkommastellen).



das wäre echt super ... wenn du division am ende nicht wieder alles kaputt machen würde ...

ich erinnere mal an das beispiel von wikipedia ... 129/40 sind für einen menschen glatt 12,45 ... für den rechner wäre es eine unendliche binär-darstellung ... wesshalb dann nicht 12,45 rauskommt .. sondern alles andere *was halt am nächsten endlich binär darstellbar ist*

von daher würde ich BigDecimal nicht nur für beliebig große zahlen verwenden ... sondern auch für beliebig genaue ...


----------



## faetzminator (12. Mrz 2012)

irgendjemand hat gesagt.:


> das wäre echt super ... wenn du division am ende nicht wieder alles kaputt machen würde ...


Eigentlich sollte das ohne Probleme funktionieren, da x/10 IMHO sowohl als double als auch als float ohne Wertverlust gespeichert werden sollte!? Die exakten "Einschränkungen" bzw. Definitionen der Datentypen sind mir aber ehrlich gesagt nicht bekannt.



irgendjemand hat gesagt.:


> ich erinnere mal an das beispiel von wikipedia ... 129/40 sind für einen menschen glatt 12,45 [...]


Also für mich wärs wohl eher 3.225 



irgendjemand hat gesagt.:


> von daher würde ich BigDecimal nicht nur für beliebig große zahlen verwenden ... sondern auch für beliebig genaue ...



Es kommt halt immer auf die Genauigkeit drauf an. Wenn du 25 Nachkommastellen supporten musst, dann ist BigDecimal sicher eine Überlegung wert.


----------



## irgendjemand (12. Mrz 2012)

faetzminator hat gesagt.:


> Eigentlich sollte das ohne Probleme funktionieren, da x/10 IMHO sowohl als double als auch als float ohne Wertverlust gespeichert werden sollte!? Die exakten "Einschränkungen" bzw. Definitionen der Datentypen sind mir aber ehrlich gesagt nicht bekannt.


hmm ... x/10 ist für den rechner aber weit aufwändiger als für uns menschen einfach die letzte stelle zu entfernen *falls "0"* bzw das komma eine stelle nach links zu rücken
für den rechner ist x/2 sehr viel einfacher da er dabei nur bit-shifting machen muss


faetzminator hat gesagt.:


> Also für mich wärs wohl eher 3.225


ja ... ich hatte es nicht mehr im kopf ... das beispiel von wiki war : 249/20 ... mein fehler xD


faetzminator hat gesagt.:


> Es kommt halt immer auf die Genauigkeit drauf an. Wenn du 25 Nachkommastellen supporten musst, dann ist BigDecimal sicher eine Überlegung wert.


soweit würde ich noch nicht mal gehen ...
ich würde es schon einsetzen wenn ich wüsste das z.b. 0.3 nicht richtig dargestellt werden kann obwohl ich es so deklariert habe ...
es kommt also nicht nur darauf an wie genau es sein muss *also 100 nachkommastellen* sondern auch darauf ob ein primitiver datentyp in der lage ist einen gewissen wert richtig darzustellen ... was bei TO bei 0.3 nicht der fall zu sein scheint ...


----------

