Tim Graf: Berechnung von Fließkommazahlen

alert(1.5 - 1.0);

-> 1

alert(1.4 - 1.0);

-> 0.3999999999999999

Sämtliche von mir getestete Browser zeigen hier das gleiche Verhalten. Hat Jemand eine Erklärung dafür?

Gruß,
Tim

  1. alert(1.5 - 1.0);

    -> 1

    Ähm, ich meine natürlich hier kommt 0.5 heraus!

  2. alert(1.5 - 1.0);

    -> 1

    alert(1.4 - 1.0);

    -> 0.3999999999999999

    Sämtliche von mir getestete Browser zeigen hier das gleiche Verhalten. Hat Jemand eine Erklärung dafür?

    Das hängt damit zusammen, wie Computer rechnen: http://dcljs.de/faq/antwort.php?Antwort=rechnen_rechnen#2

    Struppi.

  3. Moin Moin !

    <klugscheiß>
    Die korrekte Übersetzung für "floating point number" ist Gleitkommazahl, nicht Fließkommazahl. Denn im Gegensatz zur "fixed point" Rechnerei, die Zahlen einfach als Integer behandelt und an passender Stelle das Dezimaltrennzeichen einblendet, ist die Position des Dezimaltrennzeichens bei "floating point" Rechnerei variabel.
    </klugscheiß>

    Alexander

    --
    Nein, ich beantworte keine Fragen per eMail. Dafür ist das Forum da.
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
  4. Moin Moin ! (nochmal)

    Laß mich raten: Du willst zwei Gleitkommazahlen vergleichen. Das ist ein Standardverfahren der numerischen Mathematik: Du vergleichst den Betrag der Differenz der beiden Zahlen mit einer sehr kleinen, aber noch fehlerfrei darstellbaren Zahl Epsilon. Ist der Betrag kleiner als Epsilon, sind die Zahlen identisch. Genauso prüft man auf Null.

    Die genaue Größe von Epsilon ist ziemlich egal, man nimmt meistens eine glatte Zehnerpotenz zwischen 10^-5 und 10^-30. Die Größenordung hängt stark vom Problem und den erwarteten Zahlenwerten ab.

    var epsilon=1.0E-6;

    function areFloatsEqual(a,b)
    {
      return (Math.abs(a-b)<epsilon);
    }

    function isFloatNull(f)
    {
      return (Math.abs(f)<epsilon);
    }

    Beide Funktionen kann man auch durch die jeweils andere ausdrücken:

    function isFloatNull(f)
    {
      return areFloatsEqual(f,0);
    }

    function areFloatsEqual(a,b)
    {
      return isFloatNull(a-b);
    }

    Übrigens: Eine sehr kleine Zahl als Divisor kann sehr fatale Folgen haben, insbesondere wenn man eigentlich eine wesentlich größere Zahl erwartet, deswegen sollte man bei der Division vorsichtig sein:

    function divFloat(a,b)
    {
      if (isFloatNull(b)) {
        alert('Division by 0 error');
      } else {
        return (a/b);
      }
    }

    Mehr dazu sollte in jedem Buch / Vorlesungsscript zu numerischer Mathematik zu finden sein.

    Alexander

    --
    Nein, ich beantworte keine Fragen per eMail. Dafür ist das Forum da.
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"