double verhällt sich ungenau



  • Hallo,

    wenn ich eine double wie folgt definiere:

    double d = 3.2;
    

    Dann befindet sich bei mir folgendes im Speicher: 3.2000000000000002

    Das macht ja mal irgendwie überhaupt keinen Sinn? (Ich benutze VS2003 falls es daran liegen sollte?).

    Bei einigen anderen Werten, z.B. 4.0 ist alles korrekt, also nur Nullen hinter der 4.

    Ratlos ~fog



  • Es liegt nicht am Compiler, und es macht Sinn wenn man sich anschaut wie Fließkommazahlen dargestellt werden: http://de.wikipedia.org/wiki/IEEE_754



  • Das Problem ist grundsätzlicher Natur: double speichert seine Werte als Binärzahl in halblogarithmischer Darstellung - und da können einige Werte nicht exakt dargestellt werden (die werden dann entsprechend gerundet).

    (versuch doch mal aus Spaß, die Zahl 3.2 in binärer Form hinzuschreiben - oder 1/3 exakt als Dezimalzahl darzustellen)



  • Das liegt daran, dass Zahlen im "Binärformat" gespeichert werden. Kann man auch nichts gegen machen, die Ungenauigkeit hast du immer drin. Wenn man float/double-Zahlen vergleicht, nimmt man sich idR ein kleines delta (z.B. 0,000001) und prüft, ob die Differenz der beiden zu Prüfenden kleiner als Delta ist, wenn ja, sind sie "gleich".
    menno...



  • Ok,

    Dann muss ich wohl die delta methode benutzen. Bekomme von einer Funktion 0.70000000000000007 zurück für 0.7 (warum auch immer), und wenn ich 0.7 selber definiere benutzt er 0.69999999999999996 wodurch der Vergleichsoperator verständlicherweise nicht glücklich ist.

    Ist ja ganz schön umständlich jedes mal zwei Schranken definieren zu müssen mit denen man dann vergleichen kann.

    Danke für die fixen und ausführlichen Antworten :-), hatte gar nicht an Binärdarstellung gedacht.

    Grüße ~fog



  • das du "0.70000000000000007" zurueckbekommst ist doch normal:
    Stichwort "Wertebereich"

    Bei PC-Systemen gilt im allgemeinen:
               Bitanzahl n   Wertebereich                Genauigkeit
      float        32        1.5E-45   .. 3.4E38          7- 8 Stellen
      double       64        5.0E-324  .. 1.7E308        15-16 Stellen
      long double  80        1.9E-4951 .. 1.1E4932       19-20 Stellen
    

    mit der 7 bist du genau um eine stelle drueber, um genauer zu werden brauchst du dann long double


Anmelden zum Antworten