Ich arbeite täglich mit Python 2.4 in meiner Firma. Ich benutzte die vielseitige Logarithmusfunktion 'log' aus der Standard-Mathematikbibliothek, und als ich log (2 ** 31, 2) eingab, gab es 31,000000000000004 zurück, was mir etwas merkwürdig vorkam.
Ich habe das Gleiche mit anderen Zweierpotenzen gemacht, und es hat perfekt funktioniert. Ich lief 'log10 (2 ** 31) / log10 (2)' und ich bekam eine Runde 31.0
Ich habe versucht, dieselbe ursprüngliche Funktion in Python 3.0.1 auszuführen, vorausgesetzt, dass es in einer fortgeschritteneren Version behoben wurde.
Warum passiert das? Ist es möglich, dass es in Python einige Ungenauigkeiten in mathematischen Funktionen gibt?
Dies ist mit Computerarithmetik zu erwarten. Es folgt bestimmten Regeln wie IEEE 754 , die wahrscheinlich nicht mit der Mathematik übereinstimmen, die Sie in der Schule gelernt haben.
Wenn dies wirklich wichtig ist, verwenden Sie den Dezimaltyp von Python.
Beispiel:
%Vor%Immer nehmen an, dass Fließkommaoperationen einen Fehler enthalten und auf Gleichheit prüfen, wobei dieser Fehler berücksichtigt wird (entweder ein Prozentwert wie 0,00001% oder ein fester Wert wie 0,00000000001). Diese Ungenauigkeit ist gegeben, da nicht alle Dezimalzahlen binär mit einer festen Anzahl von Bits Genauigkeit dargestellt werden können.
Ihr besonderer Fall ist keiner von ihnen, wenn Python IEEE754 verwendet, da 31 mit einfacher einfacher Genauigkeit darstellbar sein sollte. Es ist jedoch möglich, dass es in einem der vielen Schritte, die es zum Berechnen von log 2 31 benötigt, an Genauigkeit verliert, weil es einfach keinen Code zum Erkennen spezieller Fälle wie a hat direkte Macht von zwei.
Fließkommaoperationen sind niemals exakt. Sie geben ein Ergebnis mit einem akzeptablen relativen Fehler für die Sprache / Hardware-Infrastruktur zurück.
Im Allgemeinen ist es ziemlich falsch anzunehmen, dass Gleitkommaoperationen präzise sind, insbesondere mit einfacher Genauigkeit. Abschnitt "Genauigkeitsprobleme" von Wikipedia Fließkomma-Artikel:)
IEEE-Doppel-Gleitkommazahlen haben <521> . Seit 10 ^ 15 & lt; 2 ^ 52 & lt; 10 ^ 16, ein Doppel hat zwischen 15 und 16 signifikante Zahlen. Das Ergebnis 31.000000000000004 ist korrekt auf 16 Ziffern, also ist es so gut wie man es erwarten kann.
Die repr
ementation ( float.__repr__
) einer Zahl in Python versucht, eine Zahl von Ziffern so nahe wie möglich an den reellen Wert zurückzugeben, wenn die IEEE-754-Arithmetik bis zu einer bestimmten Grenze genau ist. In jedem Fall, wenn Sie print
ed das Ergebnis, würden Sie nicht bemerken:
print
konvertiert seine Argumente in Strings (in diesem Fall durch die float.__str__
-Methode), die die Ungenauigkeit durch weniger Ziffern anzeigt:
in der Regel unbrauchbar 'Antwort ist sehr nützlich, eigentlich:)
Tags und Links python math floating-point