Ungenauer Logarithmus in Python

8

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?

    
Avihu Turzion 31.05.2009, 12:48
quelle

7 Antworten

44

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%     
Matthew Flaschen 31.05.2009, 12:55
quelle
19

Sie sollten lesen "Was jeder Informatiker über Gleitkommaarithmetik wissen sollte".

Ссылка

    
bayer 31.05.2009 14:08
quelle
17

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.

    
paxdiablo 31.05.2009 12:58
quelle
5

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:)

    
NicDumZ 31.05.2009 13:01
quelle
3

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.

    
John D. Cook 31.05.2009 19:09
quelle
2

Das ist normal. Ich würde erwarten, dass log10 genauer ist als log (x, y), da es genau weiß, was die Basis des Logarithmus ist, auch kann es eine Hardware-Unterstützung für die Berechnung von Logarithmen der Basis 10 geben.

    
quant_dev 31.05.2009 13:04
quelle
1

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:

%Vor%

print konvertiert seine Argumente in Strings (in diesem Fall durch die float.__str__ -Methode), die die Ungenauigkeit durch weniger Ziffern anzeigt:

%Vor%

in der Regel unbrauchbar 'Antwort ist sehr nützlich, eigentlich:)

    
tzot 31.05.2009 19:53
quelle

Tags und Links