Matthias Stricker: PHP CAST-Problem oder was?

Hallo,

ich habe folgendes Problem.

ich habe folgendes Konstrukt:

$wert_1 = pow(12*13,15);
$wert_2 = [12*13,15];

==> '[' wird mit 'pow(' und ']' mit ');' ersetzt und das Ergebnis mitels eval(); errechnet.

Ergebnis:

$wert_1 = 7.8862215xxxxxxE32
$wert_2 = 7.8862215xxxxxxE32

ABER, wenn ich $wert_1 - $wert_2 rechne kommt statt 0, 59000xxxxxxx
raus, das kann doch nicht sein, woher kommt so eone gigantische Abweichung?

Hat jemand eine Idee?

Grüße, Matthias

  1. hi,

    ABER, wenn ich $wert_1 - $wert_2 rechne kommt statt 0, 59000xxxxxxx
    raus, das kann doch nicht sein, woher kommt so eone gigantische Abweichung?

    An der begrenzten Genauigkeit, mit der ein binärer Rechner Dezimalbrüche berechnen kann.

    http://de.wikipedia.org/wiki/Gleitkommazahl
    http://www.php.net/manual/de/language.types.float.php

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. Hallo Matthias,

    $wert_1 = 7.8862215xxxxxxE32
    $wert_2 = 7.8862215xxxxxxE32

    Die 'x' wären jetzt durchaus noch interessant - aber wahrscheinlich sind sie tatsächlich deckungsgleich.

    ABER, wenn ich $wert_1 - $wert_2 rechne kommt statt 0, 59000xxxxxxx
    raus, das kann doch nicht sein, woher kommt so eone gigantische Abweichung?

    Gemessen an den ursprünglichen Zahlenwerten ist das doch fast nichts! Ich weiß nicht, mit welcher Genauigkeit float-Werte in PHP gespeichert werden, aber gehen wir mal vom worst case aus und nehmen das IEEE-Fließkommaformat mit 32bit an. Dieses Format sieht 8bit für den Exponenten (und das Vorzeichen) vor, und 24bit für die Mantisse. 24bit entsprechen aber nur rund 8 Dezimalstellen. Das heißt, dass bei Zahlen im Bereich 1E+32 durchaus Rundungsfehler von 1E+24 auftreten können! Das Ergebnis, was du bekommst, ist also schon hervorragend genau.
    Und selbst wenn PHP intern mit dem IEEE-Format für "double precision" rechnet, das 64bit insgesamt vorsieht, davon 52bit für die Mantisse, dann sind das auch "nur" etwa 18 Dezimalstellen.
    Du darfst nie vergessen, dass auch Fließkommazahlen nur mit einer begrenzten Genauigkeit gespeichert werden!

    Schönen Abend noch,
     Martin

    --
    Was sagt die kleine Kerze zur großen Kerze?
    Ich gehe heute nacht aus!
    1. Danke für den Hinweis,

      ich hätte nur gedacht, das die Rundungsfehler bei zwei identischen Aufgaben auch gleich sind.

      Wie bloed, wie soll ich denn jetzt vergleichen, ob die Zahlen identisch sind....

      Grüße, Matthias

      1. Hallo,

        Wie bloed, wie soll ich denn jetzt vergleichen, ob die Zahlen identisch sind....

        das kannst du bei floats nicht. Nicht zuverlässig.
        Teste stattdessen, ob die Differenz dem Betrag nach kleiner ist als eine von dir festgelegte akzeptable Grenze, die natürlich von den Zahlenwerten abhängt, die üblicherweise auftreten.

        So long,
         Martin

        --
        Irgendwann in grauer Vorzeit benutzte einer unserer prähistorischen Vorfahren ein Schimpfwort anstelle der Keule.
        Die Zivilisation hatte begonnen.
      2. echo $begrüßung;

        Wie bloed, wie soll ich denn jetzt vergleichen, ob die Zahlen identisch sind....

        Rechne mit den BCMath Arbitrary Precision Mathematics Functions. Bedenke aber, dass die Genauigkeit sicherlich nicht "kostenlos" zu haben ist.

        echo "$verabschiedung $name";