2017-10-16 3 views
2

Nachdem in 3. Mathematik und dezimal importiert Ich bin OK mit dem ersten AusgangPython Dezimalgenauigkeit an der Konsole - seltsam

In[39]: Decimal(sqrt(2)) 
Out[39]: Decimal('1.4142135623730951454746218587388284504413604736328125') 

aber dann leicht flummoxed von

In[40]: Decimal(str(sqrt(2))) 
Out[40]: Decimal('1.4142135623730951') 

die wirklich verwirrt durch ...

In[41}: getcontext().prec=2 

In[42]: Decimal(str(sqrt(2))) 
Out[42]: Decimal('1.4142135623730951') 

Warum die Ausgangspräzision ist nicht für die Zukunft-2 gesetztZeilen nach der prec=2? Ich dachte, Decimal() wirft die Eingabe, ob Fließkommazahl oder int als Dezimalzahl mit der Genauigkeit festgelegt?

+1

Was sehen Sie, wenn Sie nur 'str (sqrt (2))' schreiben? – Barmar

Antwort

3

Da die docs sagen über den Decimal() Konstruktor:

Der Kontext Präzision wirkt sich nicht auf, wie viele Stellen gespeichert werden. Dies wird ausschließlich durch die Anzahl der Ziffern im Wert bestimmt. Beispiel: Dezimal ('3.00000') zeichnet alle fünf Nullen auf, auch wenn die Kontextgenauigkeit nur drei beträgt.

Eine Möglichkeit, die überschüssige Präzision zu vergießen ist die einstellige + Operator auf das Ergebnis anwenden:

>>> decimal.Decimal(str(math.sqrt(2))) 
Decimal('1.4142135623730951') 
>>> + decimal.Decimal(str(math.sqrt(2))) # note the leading "+" 
Decimal('1.4') 

Ein weiterer Grund ist ein Kontextobjekt des .create_decimal() Methode zu verwenden:

>>> decimal.getcontext().create_decimal(str(math.sqrt(2))) 
Decimal('1.4') 

Als create_decimal Die Dokumentation sagt:

Im Gegensatz zum Dezimalkonstruktor werden die Kontextgenauigkeit, die Rundungsmethode, Flags und Traps auf die Konvertierung angewendet.

+0

OK, danke. Ich hatte es als ein Casting irgendeiner Dezimalzahl auf die zuletzt angegebene Genauigkeit genommen. – user70576

2

Vom documentation:

Die Bedeutung eines neuen Decimal wird allein durch die Anzahl der Ziffern Eingabe bestimmt. Kontextgenauigkeit und Rundung kommen nur bei arithmetischen Operationen zum Tragen.

Da Sie keine Decimal(str(sqrt(2))) arithmetische Berechnungen durchführen, wird nicht die von Ihnen eingestellte Genauigkeit verwendet. Sie können dies beheben, indem Sie eine einfache arithmetische Operation hinzufügen.

In: Decimal(str(sqrt))) + 0 
Out: Decimal('1.4') 
1

zu Teil 2str(v) Ausgabe eines Schwimmers v zeigt die Darstellung für die kürzeste v == float(str(v)) wahr ist.

Python docs sagen:

Viele Anwender der Annäherung nicht bewusst sind, wegen der Art und Weise Werte angezeigt werden. Python gibt nur eine Dezimalnäherung an den tatsächlichen Dezimalwert der binären Näherung aus, die von der Maschine gespeichert wird. Auf den meisten Rechnern würde Python den wahren Dezimalwert der für 0 gespeicherten binären Approximation ausgeben.1, wäre es angezeigt haben

>>> 0.1 
0.1000000000000000055511151231257827021181583404541015625 

, dass mehr Stellen als die meisten Leute finden, nützlich ist, so Python die Anzahl der Stellen überschaubar durch einen gerundeten Wert anzeigt statt

>>> 1/10 
0.1 

Denken Sie daran hält, auch wenn das gedruckte Ergebnis sieht wie der genaue Wert von 1/10 aus, der tatsächlich gespeicherte Wert ist der nächste darstellbare Binärbruch.

In Bezug auf Teil 3, Python docs sagen:

Der Kontext Präzision wirkt sich nicht auf, wie viele Stellen gespeichert werden. Dies wird ausschließlich durch die Anzahl der Ziffern im Wert bestimmt. Beispiel: Dezimal ('3.00000') zeichnet alle fünf Nullen auf, auch wenn die Kontextgenauigkeit nur drei ist

+0

"Die Kontextgenauigkeit hat keinen Einfluss darauf, wie viele Ziffern gespeichert sind. Dies wird ausschließlich durch die Anzahl der Ziffern im Wert bestimmt. Zum Beispiel, Dezimal ('3.00000') zeichnet alle fünf Nullen auf, auch wenn die Kontextgenauigkeit nur drei ist" Danke - ich habe damit gemeint, dass die Variable die vollständige Dezimal-Erweiterung beibehält ("speichert" & "Datensätze"), aber nur/print mit der aktuellen Genauigkeit verwendet. zB s = Dezimal ('') getcontext(). prec = 2 Druck (e) --- >> 0.1 #auch wenn s mit voller Genauigkeit beibehalten wird drucken (s * 10) --- >> 1.0 getcontext(). Prec = 5 Druck (e) ------ >> 0.1234 – user70576