Wie vermeidet man Gleitkommafehler?

8

Ich habe versucht, eine Funktion zu schreiben, die Quadratwurzeln annähert (ich weiß, dass es das Mathematikmodul gibt ... Ich möchte es selbst machen), und ich wurde von der Fließkomma-Arithmetik durcheinander gebracht. Wie können Sie das vermeiden?

%Vor%

Damit haben Sie folgende Ergebnisse:

%Vor%

Ich weiß, ich könnte round() verwenden, aber ich möchte das wirklich genau machen können. Ich möchte in der Lage sein, 6 oder 7 Ziffern zu berechnen. Das wäre nicht möglich, wenn ich mich versehe. Ich möchte verstehen, wie man Fließkommaberechnungen in Python richtig behandelt.

    
Aerovistae 20.10.2013, 03:56
quelle

1 Antwort

15

Das hat wirklich nichts mit Python zu tun - Sie würden das gleiche Verhalten in jeder Sprache mit der binären Fließkommaarithmetik Ihrer Hardware sehen. Zuerst lesen Sie die Dokumentation .

Nachdem Sie das gelesen haben, werden Sie besser verstehen, dass Sie nicht ein Hundertstel in Ihrem Code hinzufügen. Genau das fügst du hinzu:

%Vor%

Diese Zeichenkette zeigt den exakten Dezimalwert der binären Gleitkommazahl ("doppelte Genauigkeit" in C) Approximation auf den genauen Dezimalwert 0.01. Das Ding, das du wirklich hinzufügst, ist etwas größer als 1/100.

Das Steuern numerischer Gleitkommafehler ist das Feld "numerische Analyse" und ist ein sehr großes und komplexes Thema. Solange Sie sich darüber wundern, dass Gleitkommazahlen nur Näherungen für Dezimalwerte sind, verwenden Sie das Modul decimal . Das wird dir eine Welt von "oberflächlichen" Problemen nehmen. Zum Beispiel, angesichts dieser kleinen Änderung an Ihrer Funktion:

%Vor%

dann:

%Vor%

Es ist nicht wirklich genauer, aber in einfachen Beispielen vielleicht weniger überraschend, denn jetzt fügt genau ein Hundertstel hinzu.

Eine Alternative ist es, bei floats zu bleiben und etwas hinzuzufügen, das genau als binäres float darstellt: Werte der Form I/2**J . Anstatt beispielsweise 0,01 hinzuzufügen, fügen Sie 0,125 (1/8) oder 0,0625 (1/16) hinzu.

Dann schauen Sie nach "Newtons Methode" für die Berechnung von Quadratwurzeln; -)

    
Tim Peters 20.10.2013, 04:18
quelle