Wie kann man mit Python auf 2 Dezimalstellen runden?


253

Ich bekomme viele Dezimalstellen in der Ausgabe dieses Codes (Fahrenheit in Celsius Konverter).

Mein Code sieht derzeit so aus:

def main():
    printC(formeln(typeHere()))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(answer)
    print "\nYour Celsius value is " + answer + " C.\n"



main()

Meine Frage ist also, wie mache ich das Programm um jede Antwort auf die 2. Dezimalstelle?


6
Eine kleine Bemerkung zu Ihrem Code. Es gibt keinen Grund, den Fahrenheit-Wert als global beizubehalten. Es reicht aus (und ist besser), ihn als Parameter an Ihre Funktionen zu übertragen. Entfernen Sie also die Zeile "Global Fahrenheit". Benennen Sie in der Formeln-Funktion den Parameter in die Funktion "Fahreinheit" um. Für die Rundung können Sie nur die "%" -Parameter verwenden, um nur die ersten 2 Ziffern anzuzeigen, und es sollte für diese Ziffern gerundet werden. Die Anzahl der in der Formel in Formeln angegebenen Ziffern hat keine Auswirkung.
Arieli

Antworten:


443

Sie können die roundFunktion verwenden, die als erstes Argument die Zahl und als zweites Argument die Genauigkeit nach dem Dezimalpunkt verwendet.

In Ihrem Fall wäre es:

answer = str(round(answer, 2))


21
Das nennt man Bankrundung. Es rundet auf die gerade Zahl zu. Es ist im IEEE 754-Standard für Gleitkommazahlen enthalten. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz

37
Ich bin mir nicht sicher, was die Leute dazu veranlasst hat, den obigen Kommentar zu unterstützen. Für die Aufzeichnung, die Tatsache, round(2.675, 2)die 2.67eher gibt als 2.68überhaupt nichts mit Bankers Rundung zu tun hat.
Mark Dickinson

3
Hinweis : Dies ändert den Wert der Antwort. Wenn Sie nur für die Anzeige runden möchten, lesen Sie die Antwort von @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth

4
@ Johnsyweb Ich versuche es heute, ein Jahr nach dem ursprünglichen Beitrag, und es sieht wie erwartet aus. Scheint rund () im Laufe der Zeit entwickelt. Siehe unten: Runde (1.379, 2) -> 1.38 Runde (1.372, 2) -> 1.37 Runde (1.375, 2) -> 1.38
NightFurry

81

Verwenden str.format()der Syntax von ' zur Anzeige answer mit zwei Dezimalstellen (ohne den zugrunde liegenden Wert von zu ändern answer):

def printC(answer):
    print("\nYour Celsius value is {:0.2f}ºC.\n".format(answer))

Wo:

  • :führt die Formatspezifikation ein
  • 0 Aktiviert das vorzeichenbewusste Null-Auffüllen für numerische Typen
  • .2setzt die Genauigkeit auf2
  • f Zeigt die Nummer als Festkommazahl an

3
Dies ist die nützlichste Antwort IMO - hält den tatsächlichen Wert intakt und ist einfach zu implementieren! Vielen Dank!
BrettJ

Ich weiß nicht warum, aber das Format '{: 0.2f}' (0.5357706) gibt mir '0.54' (Python 3.6)
Noam Peled

3
@ NoamPeled: Warum sollte es nicht? 0.5357...ist näher 0.54als als 0.53, also 0.54macht das Runden auf Sinn.
ShadowRanger

"{:0.2f}".format(1.755)-> 1,75 "{:0.2f}".format(1.7551)-> 1,76 - Allerdings hätte ich beide mit 1,76 gerechnet.
Janothan

(Python Version: 3.6.10)
Janothan

48

Die meisten Antworten vorgeschlagen roundoder format. roundManchmal wird aufgerundet , und in meinem Fall musste der Wert meiner Variablen abgerundet und nicht nur als solcher angezeigt werden.

round(2.357, 2)  # -> 2.36

Ich habe hier die Antwort gefunden: Wie runde ich eine Gleitkommazahl auf eine bestimmte Dezimalstelle auf?

import math
v = 2.357
print(math.ceil(v*100)/100)  # -> 2.36
print(math.floor(v*100)/100)  # -> 2.35

oder:

from math import floor, ceil

def roundDown(n, d=8):
    d = int('1' + ('0' * d))
    return floor(n * d) / d

def roundUp(n, d=8):
    d = int('1' + ('0' * d))
    return ceil(n * d) / d

1
Ich habe gestimmt - das habe ich gesucht; Ich mag deine Arbeit mit Python-Poloniex: D
Skylar Saveland

2
"Werte werden auf das nächste Vielfache von 10 der Potenz minus Ndigits gerundet;" docs.python.org/3/library/functions.html#round also nein, Runde wird nicht immer aufgerundet , zBround(2.354, 2) # -> 2.35
Pete Kirkham

@PeteKirkham Sie haben Recht, ich habe meine Antwort bearbeitet, um mehr Sinn und Genauigkeit zu machen.
s4w3d0ff

2
-0,54 ist die richtige Antwort für die Abrundung von -0,5357706, da es sich um eine negative Zahl handelt, -0,54 <-0,53
s4w3d0ff

2
Ich würde 10**danstelle von verwenden int('1' + ('0' * d)).
Jonathon Reinhart

11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))

8

Sie möchten Ihre Antwort abrunden.

round(value,significantDigit)ist die übliche Lösung, um dies zu tun, jedoch funktioniert dies manchmal nicht so, wie man es aus mathematischer Sicht erwarten würde, wenn die Ziffer, die der Ziffer, auf die Sie runden, unmittelbar unter (links von) liegt, eine hat 5.

Hier einige Beispiele für dieses unvorhersehbare Verhalten:

>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01

Angenommen, Sie beabsichtigen, die traditionelle Rundung für Statistiken in den Wissenschaften durchzuführen, ist dies ein praktischer Wrapper, damit die roundFunktion wie erwartet funktioniert und importzusätzliche Dinge wie erforderlich sind Decimal.

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*6),2)

0.08

Aha! Auf dieser Grundlage können wir also eine Funktion erstellen ...

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

Grundsätzlich fügt dies der Zeichenfolge einen wirklich kleinen Wert hinzu, um zu erzwingen, dass sie in unvorhersehbaren Fällen, in denen sie normalerweise nicht mit der roundFunktion übereinstimmt, wenn Sie dies erwarten , ordnungsgemäß aufgerundet wird. Ein praktischer Mehrwert zu schaffen ist , 1e-Xwo Xdie Länge der Zahlenfolge ist sind Sie zu verwenden versuchen , roundauf Plus 1.

Der Ansatz der Verwendung 10**(-len(val)-1)war bewusst, da er die größte kleine Zahl ist, die Sie hinzufügen können, um die Verschiebung zu erzwingen, und gleichzeitig sicherstellt, dass der hinzugefügte Wert die Rundung niemals ändert, selbst wenn die Dezimalstelle .fehlt. Ich könnte nur 10**(-len(val))mit einer Bedingung verwenden, if (val>1)um 1mehr zu subtrahieren ... aber es ist einfacher, immer die zu subtrahieren, 1da dies den anwendbaren Bereich von Dezimalzahlen, mit dem diese Problemumgehung richtig umgehen kann, nicht wesentlich ändert. Dieser Ansatz schlägt fehl, wenn Ihre Werte die Grenzen des Typs erreichen. Dies schlägt fehl, aber für fast den gesamten Bereich gültiger Dezimalwerte sollte er funktionieren.

Der fertige Code lautet also wie folgt:

def main():
    printC(formeln(typeHere()))

def roundTraditional(val,digits):
    return round(val+10**(-len(str(val))-1))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(roundTraditional(answer,2))
    print "\nYour Celsius value is " + answer + " C.\n"

main()

... sollte Ihnen die Ergebnisse liefern, die Sie erwarten.

Sie können auch die Dezimalbibliothek verwenden, um dies zu erreichen. Der von mir vorgeschlagene Wrapper ist jedoch einfacher und kann in einigen Fällen bevorzugt werden.


Edit: Danke Blckknght für den Hinweis, dass der Randfall hier5 nur für bestimmte Werte auftritt .


6

Verwenden Sie einfach die Formatierung mit% .2f, um auf 2 Dezimalstellen abzurunden.

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

4

Sie können den Zeichenfolgenformatierungsoperator von Python "%" verwenden. "% .2f" bedeutet 2 Nachkommastellen.

def typeHere():
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(Fahrenheit):
    Celsius = (Fahrenheit - 32.0) * 5.0/9.0
    return Celsius

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

def main():
    printC(formeln(typeHere()))

main()

http://docs.python.org/2/library/stdtypes.html#string-formatting


4

Sie können den runden Operator für bis zu 2 Dezimalstellen verwenden

num = round(343.5544, 2)
print(num) // output is 343.55

3

Sie können die Rundungsfunktion verwenden.

round(80.23456, 3)

wird Ihnen eine Antwort von 80.234 geben

In Ihrem Fall verwenden

answer = str(round(answer, 2))

Hoffe das hilft :)


2

Wenn Sie ein Gleitkomma-Problem vermeiden müssen beim Runden von Zahlen für die Abrechnung , können Sie numpy round verwenden.

Sie müssen numpy installieren:

pip install numpy

und der Code:

import numpy as np

print(round(2.675, 2))
print(float(np.round(2.675, 2)))

druckt

2.67
2.68

Sie sollten dies verwenden, wenn Sie Geld mit legaler Rundung verwalten.


1

Hier ist ein Beispiel, das ich verwendet habe:

def volume(self):
    return round(pi * self.radius ** 2 * self.height, 2)

def surface_area(self):
    return round((2 * pi * self.radius * self.height) + (2 * pi * self.radius ** 2), 2)

1

Ich weiß nicht warum, aber das Format '{: 0.2f}' (0.5357706) gibt mir '0.54'. Die einzige Lösung, die für mich funktioniert (Python 3.6), ist die folgende:

def ceil_floor(x):
    import math
    return math.ceil(x) if x < 0 else math.floor(x)

def round_n_digits(x, n):
    import math
    return ceil_floor(x * math.pow(10, n)) / math.pow(10, n)

round_n_digits(-0.5357706, 2) -> -0.53 
round_n_digits(0.5357706, 2) -> 0.53

Dies ist Abschneiden, nicht Runden.
ShadowRanger


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.