2015-06-10 5 views
8

Während der Programmierung bemerkte ich einen Unterschied zwischen dem Ergebnis von math.exp (2) und math.e ** 2. Wie Sie unten sehen können, tritt dieser Unterschied bei der Berechnung von e^1 nicht auf.Unterschied zwischen math.exp (2) und math.e ** 2

Da ich kein erfahrener Programmierer bin, habe ich mich gefragt, warum das anders ist? Ich nehme an, es hat etwas mit dem Aufrunden zu tun. Die Python-Dokumentation sagt, dass math.exp(x)e**x zurückgeben, aber dies scheint nicht genau richtig zu sein. Wie kommt es, dass die math.exp(x) Operation unterscheidet sich von math.e**x?

>>> math.exp(1) 
2.718281828459045 
>>> math.e**1 
2.718281828459045 
>>> math.exp(1)==math.e**1 
True 
>>> math.exp(2) 
7.38905609893065 
>>> math.e**2 
7.3890560989306495 
>>> math.exp(2)==math.e**2 
False 
>>> math.exp(100) 
2.6881171418161356e+43 
>>> math.e**100 
2.6881171418161212e+43 
>>> math.exp(100)==math.e**100 
False 
+2

Related: http://stackoverflow.com/a/15322395/1639625 Meine Vermutung: 'math.exp' ist in' c' (oder sogar in Hardware) implementiert und hat daher etwas anderes Fließkommaverhalten. –

+1

Abstimmung zum erneuten Öffnen. Hier ist mehr los als einfach "Gleitkomma ist ungenau". Insbesondere, wie die beiden Antworten erklären, gibt es gute Gründe zu erwarten, dass exp (x) genauer ist als e x. –

Antwort

4

Es ist anders wegen der Unterschiede in der Implementierung der Funktionen. Keiner ist perfekt aufgrund der Natur des Fließpunktes.

Der Operator ** ist in floatobject.c implementiert und enthält viele Sonderfälle, von denen jedoch keiner hier aufgerufen wird, so dass er letztendlich die Standard-C pow-Funktion erreicht. Die math.pow Funktion macht schließlich das Gleiche.

Die Funktion exp ist ein einfacher Wrapper um die gleichnamige C-Funktion, definiert mit einem Makro in mathmodule.c.

Da es passiert, ist exp genauer (beide Ergebnisse stimmen überein, innerhalb der Genauigkeit, die durch Gleitkomma erlaubt wird, hochpräzise Antworten, die ich in bc berechnete). Wahrscheinlich ist es, weil intern pow, wird die erweiterte Genauigkeit Logarithmus des mit doppelter Genauigkeit e Wertes berechnen Sie als erstes Argument übergeben, die etwas kleiner ist als 1.


Das grundlegende Problem ist, dass math.e, das ist die Zahl, die Sie die Leistung sind zu berechnen, ist:

2.718281828459045 09079559829... 

Während der reale Wert der e

2.718281828459045 23536028747... 
ist

Und dieser Fehler ist komplizierter, wenn Sie pow oder ** verwenden, während es möglicherweise nicht (oder intern möglicherweise einen höheren Genauigkeitswert verwenden), wenn Sie exp aufgrund der Details der Algorithmen verwenden.

+0

Für mein Verständnis: Was ist BC? – oscarwhiskybravo

+0

@ rosie2go Es ist ein willkürlicher Befehlszeilenrechner für Unix- und Linux-Systeme - da es eine beliebige Genauigkeit ist, kann ich es auf 50 Stellen setzen und dieses Ergebnis mit dem Python-Float-Ergebnis vergleichen. – Random832

+0

Also wird die ganze Zahl 1 0.9999999999999999468198834395860075119344401173293590545654296875, wenn Sie es zu einem Float ändern? – oscarwhiskybravo

5

exp(x) wird auf einem viel niedrigeren Niveau als e**x umgesetzt. Es ist im Wesentlichen ein Wrapper für eine Funktion in libc. Diese Funktion ist wahrscheinlich (auf irgendeiner Ebene) mit der Taylor series Erweiterung, um den Wert direkt zu berechnen (oder möglicherweise eine andere mathematische Methode, ich bin mir nicht sicher).

Auf der anderen Seite nimmt e**x eine Nummer und erhöht es auf eine Leistung. Dies ist eine völlig andere Strategie und wahrscheinlich in den meisten Fällen weniger präzise. Es ist schwierig, die Anzahl an Mächten zu erhöhen.