17 Stimmen

Unkorrekter Logarithmus in Python

Ich arbeite täglich mit Python 2.4 in meinem Unternehmen. Ich habe die vielseitige Logarithmusfunktion 'log' aus der Standard-Mathematik-Bibliothek verwendet, und als ich log(2**31, 2) eingegeben habe, hat sie 31.000000000000004 zurückgegeben, was mich etwas seltsam erschien.

Ich habe dasselbe mit anderen Potenzen von 2 gemacht, und es hat einwandfrei funktioniert. Ich habe 'log10(2**31) / log10(2)' ausgeführt und 31.0 erhalten.

Ich habe versucht, dieselbe originale Funktion in Python 3.0.1 auszuführen, in der Hoffnung, dass es in einer fortschrittlicheren Version behoben wurde.

Warum passiert das? Ist es möglich, dass es Ungenauigkeiten in mathematischen Funktionen in Python gibt?

0 Stimmen

Duplikat der immerwährenden Frage zu Gleitkommazahlen (warum erhalte ich Gleitkommazerros?), kann die beste Duplikatfrage nicht finden, vielleicht kann jemand anderes helfen.

0 Stimmen

Ich möchte darauf hinweisen, dass Python 3 den Gleitkommafehler nicht behoben hat. Stattdessen verwendet die Druckausgabe einen intelligenten Algorithmus, um den beabsichtigten Gleitkommawert anzuzeigen, anstelle des Fehlers.

54voto

Matthew Flaschen Punkte 266507

Dies ist bei der Rechnerarithmetik zu erwarten. Sie folgt bestimmten Regeln, wie z.B. 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:

from decimal import Decimal, Context
ctx = Context(prec=20)
two = Decimal(2)
ctx.divide(ctx.power(two, Decimal(31)).ln(ctx), two.ln(ctx))

21voto

bayer Punkte 6687

Du solltest "Was jeder Informatiker über Fließkommazahlen wissen sollte" lesen.

http://docs.sun.com/source/806-3568/ncg_goldberg.html

18voto

paxdiablo Punkte 809679

Immer davon ausgehen, dass Gleitkommazahlen eine gewisse Fehleranfälligkeit haben und bei der Gleichheitsprüfung diesen Fehler berücksichtigen (entweder einen prozentualen Wert wie 0,00001% oder einen festen Wert wie 0,00000000001). Diese Ungenauigkeit ist gegeben, da nicht alle Dezimalzahlen im Binärsystem mit einer festen Anzahl von Bit-Genauigkeiten dargestellt werden können.

In Ihrem speziellen Fall ist dies nicht der Fall, wenn Python IEEE754 verwendet, da 31 auch mit einfacher Genauigkeit leicht darstellbar sein sollte. Es ist jedoch möglich, dass es an Genauigkeit verliert, wenn es bei einem der vielen Schritte zur Berechnung von log2231 verwendet wird, einfach weil es keinen Code hat, um spezielle Fälle wie eine direkte Zweierpotenz zu erkennen.

6voto

Nicolas Dumazet Punkte 7080

Fließkommaoperationen sind nie genau. Sie liefern ein Ergebnis, das einen akzeptablen relativen Fehler für die Sprach-/Hardware-Infrastruktur aufweist.

Im Allgemeinen ist es ziemlich falsch anzunehmen, dass Fließkommaoperationen genau sind, insbesondere bei einfacher Genauigkeit. Abschnitt "Genauigkeitsprobleme" aus dem Wikipedia-Artikel zur Fließkommadarstellung :)

3voto

John D. Cook Punkte 28817

IEEE double floating point numbers have 52 Bits Präzision. Da 10^15 < 2^52 < 10^16 ist, hat ein Double zwischen 15 und 16 signifikante Stellen. Das Ergebnis 31.000000000000004 ist auf 16 Stellen genau, daher ist es so gut, wie man es erwarten kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X