Vergleichen Dezimalzahlen in python
Ich möchte in der Lage sein zu vergleichen, die Dezimalstellen in Python. Im Interesse der Berechnungen mit Geld, kluge Leute mir zu Dezimalzahlen anstelle von floats, also Tat ich es. Jedoch, wenn ich will, um zu überprüfen, dass eine Berechnung erzeugt das erwartete Ergebnis, wie würde ich es angehen?
>>> a = Decimal(1./3.)
>>> a
Decimal('0.333333333333333314829616256247390992939472198486328125')
>>> b = Decimal(2./3.)
>>> b
Decimal('0.66666666666666662965923251249478198587894439697265625')
>>> a == b
False
>>> a == b - a
False
>>> a == b - Decimal(1./3.)
False
so, in diesem Beispiel a = 1/3 und b = 2/3, so offensichtlich b-a = 1/3 = ein, jedoch, dass nicht mit Dezimalzahlen.
Ich denke, ein Weg, es zu tun, ist zu sagen, dass ich erwarte, dass das Ergebnis 1/3, und in python Schreibe ich dies als
Decimal(1./3.).quantize(...)
und dann kann ich vergleichen wie diesem:
(b-a).quantize(...) == Decimal(1./3.).quantize(...)
So, meine Frage ist: gibt es eine bessere Möglichkeit, dies zu tun? Wie würden Sie schreiben tests für Dezimalzahlen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie nicht mit
Decimal
den richtigen Weg.In "Ihrem code", führen Sie eigentlich "klassische" floating point division -- dann konvertieren Sie das Ergebnis in eine Dezimalzahl. Der Fehler eingeführt durch schwimmt weitergegeben, um Ihre Dezimal.
In "mein code", ich habe das Dezimal division. Die Herstellung einer richtigen (aber abgeschnitten) Ergebnis bis auf die Letzte Stelle.
Über die Runden. Wenn Sie die Arbeit mit den monetären Daten, müssen Sie wissen, die Regeln verwendet werden, für die Rundung in Ihrem Unternehmen. Wenn dem nicht so ist, mit
Decimal
wird nicht automatisch alle Ihre Probleme lösen. Hier ist ein Beispiel: $100 zu teilen zwischen den 3 Gesellschaftern.Oups: missing $.01 (freie Geschenk für die bank ?)
Ihrem Wortschwall Staaten, die Sie wollen, monetäre Berechnungen, hüten Ihr Rundungsfehler. Dezimalzahlen sind eine gute Wahl, denn Sie liefert GENAUE Ergebnisse unter addition, Subtraktion, und Multiplikation mit anderen Dezimalzahlen.
Seltsam, dein Beispiel zeigt die Arbeit mit dem Bruch "1/3". Ich habe nie eingezahlt, genau "ein Drittel der ein-dollar -" in meiner bank... es ist nicht möglich, da es keine solche Währung!
Mein Punkt ist, wenn Sie tun, jede ABTEILUNG, dann werden Sie brauchen, um zu verstehen, was Sie VERSUCHEN zu tun, was die Organisation, die Richtlinien sind auf diese Art der Sache... in dem Fall sollte es möglich sein, das umzusetzen, was Sie wollen mit Dezimal-Quantisierung.
Nun-wenn Sie das TUN wirklich tun zu wollen, division von Dezimalzahlen, und Sie wollen zu tragen willkürlichen "Genauigkeit" um Sie wirklich nicht verwenden will, der
Decimal
Objekt... Sie verwenden möchtenFraction
Objekt.Mit diesem, deinem Beispiel funktionieren würde, wie diese:
OK, gut, auch einen VORBEHALT gibt:
Fraction
Objekte sind das Verhältnis von zwei ganzen zahlen, so würde man durch multiplizieren der rechten Seite macht der 10 und tragen um ad-hoc.Klingt wie zu viel Arbeit? Ja... das ist es wahrscheinlich!
So, Kopf nach hinten, um den Decimal-Objekt; Umsetzung Quantisierung/Rundung auf Dezimale Teilung und Dezimal-Multiplikation.
Floating-point-Arithmetik ist nicht korrekt :
Müssen Sie wählen Sie eine Auflösung und abschneiden, alles Vergangenheit :
Werden Sie offensichtlich bekommen einige Rundungsfehler, die wächst mit der Anzahl der Operationen so wählen Sie Ihre Auflösung gezielt.
Es ist ein anderer Ansatz, der möglicherweise Arbeit für Sie:
round(val, places)
Beispiel:
Wenn Sie möchten, erstellen Sie eine Funktion
equals_to_the_cent()
: