# 0.7+0.2



## Guest (2. Apr 2005)

hi mal ne frage :
 wieso kommt wenn ich in einen java programm 0.7+0.2 rechne 0.8999999999999999 raus?
was kann ich unternehmen damit ich das korrekte ergebnis erhalte ?


----------



## Roar (2. Apr 2005)

runden
btw: es gibt einige threads zu dem thema wo das ausführlicher erläutert wird: suchfunktion


----------



## Guest (2. Apr 2005)

das ist doch scheiße das man da erst runden muss


----------



## Wildcard (2. Apr 2005)

> das ist doch scheiße das man da erst runden muss


Dann erklär mir doch mal wie du z.B. 0.1 korrekt als Fließkommazahl darstellen willst?


----------



## Illuvatar (2. Apr 2005)

Naja, andere Sprachen schaffen das auch :?


----------



## Wildcard (2. Apr 2005)

Wildcard hat gesagt.:
			
		

> Dann erklär mir doch mal wie du z.B. 0.1 korrekt als Fließkommazahl darstellen willst?





			
				Illuvatar hat gesagt.:
			
		

> Naja, andere Sprachen schaffen das auch  :?


Nicht wirklich, das ist ein Problem der Fließkommazahlen und die sind Standard...


----------



## Illuvatar (2. Apr 2005)

Hm da hab ich aber mal nen Test gemacht (hab ich den eigentlich schonmal gepostet? kA):

Java


```
public class FloatingPointTest
{
	public static void main (String[] args)
    {
    	for (double d = 0; d < 5; d += .2){
    		System.out.println (d);
    	}
    }
}
```



> 0.0
> 0.2
> 0.4
> 0.6000000000000001
> ...



C#


```
using System;

namespace MyTest
{
	public class FloatingPointTest
	{
		public static void Main (string[] args)
		{
			for (double d = 0; d < 5; d += .2){
				Console.Out.WriteLine (d);
			}
		}
	}
}
```



> 0
> 0,2
> 0,4
> 0,6
> ...


----------



## Beni (2. Apr 2005)

Ich könnte mir gut vorstellen, dass die C#-Print-Methode noch ein bisschen rundet.

Wildcard hat schon recht, die Fliesskommazahlen können einige "einfache" Dezimalzahlen schlicht nicht darstellen.


----------



## Roar (2. Apr 2005)

ja weil c, c# etc. automatisch runden oder so.

edit: mist 1 sekunde später


----------



## Guest (2. Apr 2005)

Nöö, es ist sicherlich eine andere interne Darstellung von Dezimalzahlen.
Es gibt Sprachen, bei denen dies "normal" ist, dass sie sehr genau bei 
Fliesskommaoperationen sind. 
z.B. Clarion: Dezimal mit einer Genauigkeit von 31 Stellen vor und nach 
dem Komma. (Intern als BCD)


----------



## Wildcard (2. Apr 2005)

> Nöö, es ist sicherlich eine andere interne Darstellung von Dezimalzahlen.
> Es gibt Sprachen, bei denen dies "normal" ist, dass sie sehr genau bei
> Fliesskommaoperationen sind.


Jede Sprache die sich an die IEEE 754 hält (was meines wissens fast jede 'gängige' Sprache' einschließt) kann Zahlen wie 0.1 nicht richtig als Fließkommazahl darstellen(eigentlich überhauptnicht rein binär).
Daher schließe ich mich Roar und Beni an, und sage das ist gerundet...


----------



## 0xdeadbeef (2. Apr 2005)

Die interne Zahlendarstellung ist in C#/C/Java definitiv die gleiche (jedenfalls solange man in Java nicht strictmath benutzt). Allerdings habe ich auch den Eindruck, daß die Standardlibraries anderer Sprachen "geschickter" runden.
Daß dort aber auch nur mit Wasser gekocht wird, kann man leicht zeigen:
0.2*0.2-0.04 sollte 0 ergeben, ergibt aber auch in C++ in double gerechnet  6.93889390391e-018.


----------



## stev.glasow (2. Apr 2005)

@Illus Test:

C#


```
using System;

namespace MyTest
{
	public class FloatingPointTest
	{
		public static void Main (string[] args)
		{
			double i = 0;
			for (double d = 0; d < 5; d += 0.2){

				double dd  = d * 10;
				bool b = dd == i;
				Console.Out.WriteLine (dd + " == " + i + ": " + b);
				i+=2;
			}
			Console.Out.WriteLine (0.2*0.2-0.04 );
		} 
	}
}
```



> 0 == 0: True
> 2 == 2: True
> 4 == 4: True
> 6 == 6: False
> ...





java:

```
public class FloatingPointTest
{
	public static void main (String[] args)
    {
		double i = 0;
        for (double d = 0; d < 5; d += 0.2){

           double dd  = d * 10;
           boolean b = dd == i;
           System.out.println (dd + " == " + i + ": " + b);
           i+=2;
        }
		System.out.println  (0.2*0.2-0.04 ); 

	}
}
```



> 0.0 == 0.0: true
> 2.0 == 2.0: true
> 4.0 == 4.0: true
> 6.000000000000001 == 6.0: false
> ...


----------



## Illuvatar (2. Apr 2005)

Hm... Na gut


----------



## Gast (9. Apr 2005)

double werte kann man  nicht auf gleichheit prüfen nur auf 
< oder > , und sich einer beliebigen genauigkeit einigen 
z.b ob es 0 ist
while (!(doubleWert > 1E-6))
.
.
.
und wenn es dann halt kleiner ist hat man 0


----------



## stev.glasow (9. Apr 2005)

Klar kann man, man sollte nur drauf achten was man damit vorher gemacht hat. Evtl. vor der Prüfung runden.
Oder was meinst?


----------



## Bleiglanz (9. Apr 2005)

man SOLL nicht auf = prüfen

=> in .NET gibts da ne eigene Konstante (Epsilon)

=> in Java Double.MIN_VALUE


----------



## The_S (10. Mai 2005)

Wildcard hat gesagt.:
			
		

> Wildcard hat gesagt.:
> 
> 
> 
> ...



Und noch ein Auszug aus einem Buch:



			
				VB 6 in 21 Tagen hat gesagt.:
			
		

> Strings, Boolesche Werte, Währungsdaten, Datumswerte, Zeitwerte und die Integer-Datentypen (Byte, Integer und Long) können auf Gleichheit miteinander verglichen werden. Versuchen Sie jedoch nicht, zwei Werte mit einfacher oder mit doppelter Genauigkeit zu vergleichen. Aufgrund der Methode, wie Visual Basic Daten mit einer bestimmten Genauigkeit speichert, erscheinen zwei Werte mit einfacher Genauigkeit möglicherweise ungleich, weil Visual Basic intern eine Rundung für solche Werte vornimmt. Wenn Sie zwei Variablen mit gleicher Genauigkeit vergleichen möchten, subtrahieren Sie sie und vergleichen die Differenz, um zu prüfen, ob sie annähernd gleich sind. Diese Codierung ist mühsam, vermeiden Sie sie also, wo immer Sie können.


----------



## thE_29 (10. Mai 2005)

Btw.: C Code, wegen eurer "vorformatieren C#" Ausgabe:


```
for (double d = 0; d < 5; d += .2){
          printf("%lf\n",d);
       }
```



			
				C hat gesagt.:
			
		

> 0.000000
> 0.200000
> 0.400000
> 0.600000
> ...




Nachtrag:


```
int main(int argc, char* argv[])
{
	
	double i = 0;
	for (double d = 0; d < 5; d += 0.2)
	{
      double dd  = d * 10;
      bool b = dd == i;
      printf("%lf == %lf : %d\n",dd,i,b);
      i+=2;
    }
    printf("\n\n%lf",0.2*0.2-0.04 ); 

	return 0;
}
```



			
				C hat gesagt.:
			
		

> 0.000000 == 0.000000 : 1
> 2.000000 == 2.000000 : 1
> 4.000000 == 4.000000 : 1
> 6.000000 == 6.000000 : 0
> ...



Nachtrag2: Irgendwie sind die boolschen Vergleiche bei C,C# und Java gleich 

Nur die Rechnung kommt in C richtig raus ^^


----------



## Reality (10. Mai 2005)

Ob 0,999999999 oder 1, das ist egal, weil es ein und dasselbe sind.

1/9 = 0,1111111111111111111111111

0,11111111111 * 9 = 0,999999999999999

1/9 * 9 = 1 (kürzt sich raus)

Ergo => 0,9999999999999999 und 1 sind dasselbe.


----------



## thE_29 (10. Mai 2005)

PI = genau 3 


Naja, für mich sollten das nicht dasselbe sein, wwweil was ist wenn du wirklich mal 0,9999999 haben willst und net 1 ??


----------



## bummerland (10. Mai 2005)

dann rechnest du mit BigDecimal.


----------



## Sky (10. Mai 2005)

thE_29 hat gesagt.:
			
		

> Naja, für mich sollten das nicht dasselbe sein, wwweil was ist wenn du wirklich mal 0,9999999 haben willst und net 1 ??


Mathematisch betrachtet ist es nun aber so, dass es das gleiche ist!

0,999999999999999 entspricht nunmal 9/9 und ist somit 1!

Sorry, aber die Mathematik kann ich nicht so schnell ändern ;-)

<Edit>Hier noch ein Link zum Thema: http://de.wikipedia.org/wiki/Periode_(Mathematik) </Edit>


----------



## The_S (10. Mai 2005)

Mr. Spock hat gesagt.:
			
		

> Faszinierend!!!


----------



## Reality (10. Mai 2005)

sky80 hat gesagt.:
			
		

> thE_29 hat gesagt.:
> 
> 
> 
> ...


Jo, genau. Man kann es auch mit Worten erklären. Wenn 0,99999999 unendlich viele 9er hat, dann ist die Differenz zwischen 0,999999999 und 1 unendlich klein => ein und dasselbe.

Liebe Grüße
Reality


----------



## thE_29 (10. Mai 2005)

Jo, nur muss man auch sagen das

0,111 != 1/9 ist!

Sondern

0,111° = 1/9 (wobei ° für peridoisch ist)

Da ist halt wieder das Problem, wenn man halt wirklich mit so einer Zahl rechnet (die nicht periodisch ist, sondern einfach nur so aussieht)


----------



## LazyBoy (16. Jun 2005)

Der Thread ist zwar schon etwas älter, aber ich wollt noch was dazu sagen.
Und zwar gibt es natürlich in java auch die möglichkeit "genau" zu rechnen, und zwar mit dem package java.math, dort finden sich die Klassen BigDecimal , BigInteger und MathContext damit gibt es die Möglichkeit so genau zu rechnen wie man will, man hat nämlich die völlige Kontrolle darüber wie gerundet wird. Wie genau das funktioniert weiss ich leider auch nicht mehr, aber steht alles in der API. Ist sehr interessant.


----------

