2017-01-03 7 views
0

Sorry, ein paar Teile dieser Frage. Ich muss Berechnungen mit sehr genauer Genauigkeit durchführen.Excel-Berechnung vs. Python und dezimale Verwendung

Ich spiele mit Decimal in Python und versuche, die Berechnungen zu überprüfen. Ich glaube, um die tatsächliche Nummer zu verwenden, müssen Sie die Nummer als Zeichenfolge rechts haben? Ich führe den folgenden Code aus.

1) Für A habe ich es als float, und B ich habe es als String. Ich bekomme verschiedene Zahlen, wenn ich sie quadriere, ist das wegen der Gleitkommaarithmetik? Ist B ** 2 richtiger?

2) Bei der letzten Druckanweisung versuche ich, die Quadratwurzel zu bekommen, aber am Ende mit einer TypeError: unsupported operand type(s) for ** or pow(): 'Decimal' and 'float'. Warum das?

3) Schließlich, wenn ich versuche, 100.0897463 quadriert in Excel zu überprüfen, bekomme ich eine Antwort von 10017.95731439840000000000. Liegt der Unterschied nur an der Rundung? Was ist eine effektive Methode zur Überprüfung von Fließkomma-Berechnungen, wenn nicht durch etwas wie Excel?

A = decimal.Decimal(100.0897463) 
B = decimal.Decimal('100.0897463') 
print A ** 2 
print B ** 2 
print B ** .5 

Ruft mich diese Zahlen,

10017.95731439836401246854725 
10017.95731439836369 

Interessant ist, wenn ich den Code wie folgt ausführen, bekomme ich genau die gleichen Zahlen für beide, und sie auch nicht von den Ergebnissen Drucken ohne die Dezimalgenauigkeit. Warum sollte das sein?

print "%.20f" % A ** 2 
print "%.20f" % B ** 2 

Ergebnisse in:

10017.95731439836345089134 
10017.95731439836345089134 
+0

Die Verwendung von Excel zur Überprüfung von Python-Berechnungen ist eine schlechte Idee, da es eine eigene proprietäre Dezimalrundung hat, die von IEEE-Standards abweicht (wenn auch nur geringfügig). Beachten Sie, dass Sie den Dezimalpunkt immer vergessen und '1000897463 ** 2' als Integer berechnen können (mit der Angabe' 1001795731439836369'). Das wird keinen Rundungsfehler haben. –

Antwort

1

1) For A I have it as a float, and B I have it as a string. I get different numbers when I square them, is that because of floating point arithmetic? Is B ** 2 more correct?

B ** 2 ist richtig. A ist ungenau, weil Sie die Decimal von einer float initialisieren und keine Zeichenfolge.

2) On the last print statement, I am trying to get the square root, but end up with a TypeError: unsupported operand type(s) for ** or pow(): 'Decimal' and 'float'. Why is that?

Da Decimal ‚s Implementierung von __pow__ erwartet, dass der Parameter des gleichen Typs sein. das heißt, auch ein Decimal

B ** decimal.Decimal('0.5') 
    # this works because B and the exponent are now of the same type 

3) Lastly when I try to verify 100.0897463 squared in excel, I get an answer of 10017.95731439840000000000. Is the difference just due to rounding? What is an effective way of verifying floating point vs. decimal calculations if not through something like excel

tun die Mathematik mit der Hand. In diesem Fall können Sie sehen, dass die letzte Ziffer der zu quadrierenden Zahl 3 ist, was bedeutet, dass das Quadrat in 9 enden sollte. Dies bedeutet, dass Excel auch Rundungs-/Genauigkeitsprobleme (erwartet) hat.

  1. Ihre andere Frage

Es sieht aus wie %f ist die Decimal mit einem Schwimmer vor dem Drucken zu konvertieren. Um dies zu erleichtern, Druck mit %s:

print '%s' % (A ** 2,) 
print '%s' % (B ** 2,) 

den Unterschied zu sehen.

1

Für (1), ich denke, die Diskrepanz ist, dass für 'A', der Wert, den Sie in decimal.Decimal() eingeben, ist bereits im binären Gleitkommaformat. Für B, decimal.Decimal erstellt eine Darstellung aus einer Zeichenfolge, so dass es mehr von dem sein kann, was Sie erwarten.

# The value is already in binary floating point format. 
A = decimal.Decimal(100.0897463) 

# Conversion from string 
B = decimal.Decimal("100.0897463") 

Für (2), unterstützen decimal.Decimal Objekte den ** Operator nur mit anderen Decimal Objekte. So werden folgende Arbeiten:

print B ** decimal.Decimal("0.5") 

Für (3), ich bin nicht sicher, was Excel tut, aber ich so überprüft:

# Essentially, multiply by 1 billion so that we only need to work with 
# integers. 
x = 1000897463 
print x ** 2 
# This gives: 1001795731439836369L 

Also, Sie wissen 10017.95731439836369 der genaue Wert ist. Es gibt wahrscheinlich mehr Möglichkeiten, dies zu tun.

BTW, print "%f" % value konvertiert den Wert in Pythons Gleitkommadarstellung.