Wie wird eine Gleitkommazahl bis zu einer bestimmten Dezimalstelle gerundet?

Angenommen, ich habe 8.8333333333333339 und ich möchte es in 8.8333333333333339 konvertieren, wie kann ich dies in Python erreichen? round(8.8333333333333339, 2) ergibt 8.83 und nicht 8.84 . Ich bin neu in Python oder Programmierung im Allgemeinen.

Ich möchte es nicht als String drucken, das Ergebnis wird weiter verwendet. Weitere Informationen zu diesem Problem finden Sie in den Python-Programmiertipps von Tim Wilson: Kredit- und Zahlungsrechner .

   

8.833333333339 (oder 8.833333333333334 , das Ergebnis von 106.00/12 ), richtig auf zwei Dezimalstellen gerundet, beträgt 8.83 . Mathematisch klingt es wie, was Sie wollen, ist eine Deckenfunktion . Das in Pythons math Modul heißt ceil :

 import math v = 8.8333333333333339 print(math.ceil(v*100)/100) # -> 8.84 

Beziehungsweise bilden die Boden- und Deckenfunktionen eine reelle Zahl im Allgemeinen auf die größte vorherige oder kleinste folgende ganze Zahl ab, die null Dezimalstellen aufweist. Um sie für 2 Dezimalstellen zu verwenden, wird die Zahl zuerst mit 10 2 (oder 100) multipliziert, um die Dezimalstelle zu verschieben zeigen und wird danach von ihm geteilt, um zu kompensieren.

Wenn Sie das math aus irgendeinem Grund nicht verwenden möchten, können Sie diese (minimal getestete) Implementierung verwenden, die ich gerade geschrieben habe:

 def ceiling(x): n = int(x) return n if n-1 < x <= n else n+1 

Wie funktioniert das Problem mit dem verknüpften Kredit- und Zahlungsrechner?

Screenshot der Ausgabe des Kredit-Rechners

Aus der Stichprobenausgabe scheint es, dass sie die monatliche Zahlung aufgerundet haben , was viele den Effekt der Deckenfunktion nennen. Dies bedeutet, dass jeden Monat etwas mehr als 1/12 des Gesamtbetrages bezahlt wird. Dadurch wurde die letzte Zahlung etwas geringer als üblich - ein verbleibender Restbetrag von nur 8.76 übrig.

Ebenso wäre es normal gewesen, eine normale Rundung mit einer monatlichen Zahlung von 8.83 und einer etwas höheren Schlusszahlung von 8.87 . In der realen Welt mögen die Leute ihre Zahlungen jedoch in der Regel nicht gerne aufstocken. Daher ist es üblich, dass jede Zahlung aufgerundet wird - und das Geld wird dem Kreditgeber schneller zurückgegeben.

Das ist normal (und hat nichts mit Python zu tun), weil 8.83 nicht genau als binärer Gleitkomma dargestellt werden kann, genau wie 1/3 nicht genau in Dezimal (0.333333 … ad infinitum) dargestellt werden kann.

Wenn Sie absolute Genauigkeit sicherstellen wollen, benötigen Sie das decimal Modul:

 >>> import decimal >>> a = decimal.Decimal("8.833333333339") >>> print(round(a,2)) 8.83 

Sie möchten das Dezimalmodul verwenden, müssen aber auch den Rundungsmodus angeben. Hier ist ein Beispiel:

 >>> import decimal >>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP) Decimal('8.34') >>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) Decimal('8.33') >>> 

Ein viel einfacherer Weg ist einfach die round () -function zu verwenden. Hier ist ein Beispiel.

 total_price = float() price_1 = 2.99 price_2 = 0.99 total_price = price_1 + price_2 

Wenn Sie jetzt total_price ausdrucken würden, würden Sie es bekommen

 3.9800000000000004 

Aber wenn Sie es in einer runden () function wie folgt einschließen

 print(round(total_price,2)) 

Die Ausgabe ist gleich

 3.98 

Die function round () akzeptiert zwei Parameter. Die erste ist die Nummer, die Sie runden möchten. Die zweite ist die Anzahl der Dezimalstellen, auf die gerundet werden soll.

Wenn Sie 8,8333333333339 auf 2 Dezimalstellen runden, lautet die richtige Antwort 8,83, nicht 8,84. Der Grund dafür, dass Sie 8.83000000001 erhalten haben, ist, dass 8.83 eine Zahl ist, die nicht korrekt in binär wiedergegeben werden kann, und sie Ihnen den nächsten Wert gibt. Wenn Sie es ohne alle Nullen drucken möchten, tun Sie wie VGE sagt:

 print "%.2f" % 8.833333333339 #(Replace number with the variable?) 

Wenn Sie runden möchten, ist 8.84 die falsche Antwort. 8.833333333333 gerundet ist 8.83 nicht 8.84. Wenn Sie immer aufrunden möchten, können Sie math.ceil verwenden. Machen Sie beides in Kombination mit String-Formatierung, da das Runden einer Float-Zahl selbst keinen Sinn ergibt.

 "%.2f" % (math.ceil(x * 100) / 100) 

Nur für das Protokoll. Du könntest es so machen:

 def roundno(no): return int(no//1 + ((no%1)/0.5)//1) 

Es gibt keine Notwendigkeit für Includes / Importe

Der einfachste Weg, dies zu tun, ist die Verwendung der folgenden function, die eingebaut ist

 format() 

beispielsweise:

 format(1.242563,".2f") 

die Ausgabe wäre:

 1.24 

ähnlich:

 format(9.165654,".1f") 

Würde geben:

 9.2 

Verwenden Sie das decimal Modul: http://docs.python.org/library/decimal.html

Hier ist meine Lösung für das Round Up / Down Problem

< .5 runden ab

> = .5 runden auf

 import math def _should_round_down(val: float): if val < 0: return ((val * -1) % 1) < 0.5 return (val % 1) < 0.5 def _round(val: float, ndigits=0): if ndigits > 0: val *= 10 ** (ndigits - 1) is_positive = val > 0 tmp_val = val if not is_positive: tmp_val *= -1 rounded_value = math.floor(tmp_val) if _should_round_down(val) else math.ceil(tmp_val) if not is_positive: rounded_value *= -1 if ndigits > 0: rounded_value /= 10 ** (ndigits - 1) return rounded_value # test # nr = 12.2548 # for digit in range(0, 4): # print("{} decimals : {} -> {}".format(digit, nr, _round(nr, digit))) # output # 0 decimals : 12.2548 -> 12 # 1 decimals : 12.2548 -> 12.0 # 2 decimals : 12.2548 -> 12.3 # 3 decimals : 12.2548 -> 12.25 

Hier ist eine einfache function, dies für Sie zu tun:

 def precision(num,x): return "{0:.xf}".format(round(num)) 

Hier ist num die Dezimalzahl. X ist die Dezimalstelle bis zu der Stelle, an der eine Floating-Zahl gerundet werden soll

Vorteil gegenüber anderen Implementierungen ist, dass sie Nullen am rechten Ende der Dezimalzahl füllen können, um eine Dezimalzahl bis zu x Dezimalstellen zu bilden.

Beispiel 1:

 precision(10.2,9) 

wird 10.200000000 (bis 9 dp) zurückgeben

Beispiel 2:

 precision(10.2231,2) 

wird 10.22 (bis zu 2 dp) zurückgeben

Ich habe diesen Code:

 tax = (tax / 100) * price 

und dann dieser Code:

 tax = round((tax / 100) * price, 2) 

Runde arbeitete für mich