Jak zaokrąglić do 2 miejsc po przecinku za pomocą Pythona?

254

Otrzymuję wiele miejsc po przecinku w wyniku tego kodu (konwerter Fahrenheita na Celsjusza).

Mój kod obecnie wygląda następująco:

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()

Więc moje pytanie brzmi: jak sprawić, by program zaokrąglał każdą odpowiedź do drugiego miejsca po przecinku?

Dolcens
źródło
7
Mała uwaga dotycząca twojego kodu. Nie ma powodu, aby wartość Fahrenheita była przechowywana jako globalna, wystarczy (i lepiej) przekazać ją jako parametr do swoich funkcji. Więc usuń wiersz „globalny Fahrenheit”. W funkcji formeln zmień nazwę parametru na funkcję „Fahreinheit” formeln (Fahreinheit). Jeśli chodzi o zaokrąglanie, możesz po prostu użyć parametrów „%”, aby wyświetlić tylko pierwsze 2 cyfry, i należy je zaokrąglić dla tych cyfr. Liczba cyfr podanych we wzorze w formeln nie ma wpływu.
arieli

Odpowiedzi:

443

Możesz użyć roundfunkcji, która jako pierwszy argument przyjmuje liczbę, a drugi argument to precyzja po przecinku.

W twoim przypadku byłoby to:

answer = str(round(answer, 2))
rolisz
źródło
21
To się nazywa zaokrąglanie bankierów. Zaokrągla się w kierunku liczby parzystej. Jest w standardzie IEEE 754 dla liczb zmiennoprzecinkowych. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz
37
Nie jestem pewien, co skłoniło ludzi do głosowania za powyższym komentarzem. Dla przypomnienia, fakt, że round(2.675, 2)daje, 2.67a nie 2.68ma nic wspólnego z zaokrąglaniem Bankera.
Mark Dickinson
3
Uwaga : zmienia to wartość odpowiedzi. Jeśli chcesz po prostu zaokrąglić do wyświetlenia, skorzystaj z odpowiedzi @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth
4
@Johnsyweb Próbuję tego dzisiaj, rok po oryginalnym poście i wygląda to zgodnie z oczekiwaniami. Wydaje się, że round () ewoluował w czasie. Zobacz poniżej: runda (1.379, 2) -> 1.38 runda (1.372, 2) -> 1.37 runda (1.375, 2) -> 1.38
NightFurry 16.08.18
82

Korzystanie str.format()„s składni do wyświetlania answer z dwoma miejscami po przecinku (bez zmiany wartości podstawowej o answer):

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

Gdzie:

  • :wprowadza specyfikację formatu
  • 0 włącza znakowanie zerami dla typów numerycznych
  • .2ustawia precyzję na2
  • f wyświetla liczbę jako liczbę stałoprzecinkową
Johnsyweb
źródło
3
Jest to najbardziej przydatna odpowiedź IMO - zachowuje aktualną wartość i jest łatwa do wdrożenia! Dzięki!
BrettJ
Nie jestem pewien, dlaczego, ale format „{: 0.2f}” (0,5357706) daje mi „0,54” (python 3.6)
Noam Peled
3
@NoamPeled: Dlaczego nie? 0.5357...jest bliżej 0.54niż do 0.53, więc zaokrąglanie 0.54ma sens.
ShadowRanger
"{:0.2f}".format(1.755)-> 1,75 "{:0.2f}".format(1.7551)-> 1,76 - Jednak oczekiwałbym obu równości 1,76.
Janothan
(Wersja Python: 3.6.10)
Janothan
48

Większość odpowiedzi sugerowanych roundlub format. roundczasami zaokrągla w górę, aw moim przypadku potrzebowałem zaokrąglenia wartości mojej zmiennej, a nie tylko jej wyświetlania.

round(2.357, 2)  # -> 2.36

Znalazłem odpowiedź tutaj: jak zaokrąglić liczbę zmiennoprzecinkową do pewnego miejsca po przecinku?

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

lub:

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
s4w3d0ff
źródło
1
Głosowałem - tego właśnie szukałem; Podoba mi się twoja praca z python-poloniex: D
Skylar Saveland
2
„wartości są zaokrąglane do najbliższej wielokrotności 10 do potęgi minus ndigity;” docs.python.org/3/library/functions.html#round, więc nie, runda nie zawsze zaokrągla w górę, np.round(2.354, 2) # -> 2.35
Pete Kirkham
@PeteKirkham masz rację, zredagowałem moją odpowiedź, aby była bardziej sensowna i dokładna.
s4w3d0ff
2
-0,54 jest poprawną odpowiedzią na zaokrąglenie -0,5357706 w dół, ponieważ jest liczbą ujemną, -0,54 <-0,53
s4w3d0ff 10.04.18
2
Użyłbym 10**dzamiast int('1' + ('0' * d)).
Jonathon Reinhart
11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))
Mahadi
źródło
8

Chcesz zaokrąglić swoją odpowiedź.

round(value,significantDigit)jest zwykłym rozwiązaniem tego problemu, jednak czasami nie działa to tak, jak można by się tego spodziewać z perspektywy matematycznej, gdy cyfra bezpośrednio gorsza (na lewo od) cyfry, którą zaokrąglasz, ma 5.

Oto kilka przykładów tego nieprzewidywalnego zachowania:

>>> 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

Zakładając, że Twoim celem jest wykonanie tradycyjnego zaokrąglania dla statystyk w nauce, jest to przydatne opakowanie, aby roundfunkcja działała zgodnie z oczekiwaniami i wymagała importdodatkowych rzeczy Decimal.

>>> round(0.075,2)

0.07

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

0.08

Aha! Na tej podstawie możemy wykonać funkcję ...

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

Zasadniczo dodaje to naprawdę niewielką wartość do łańcucha, aby zmusić go do poprawnego zaokrąglenia w górę w nieprzewidywalnych przypadkach, w których zwykle nie działa z roundfunkcją, gdy się tego spodziewasz. Wygodną wartością do dodania jest to, 1e-Xgdzie Xjest długość ciągu liczbowego, którego próbujesz użyć roundna plus 1.

Podejście polegające na użyciu 10**(-len(val)-1)było celowe, ponieważ jest to największa mała liczba, jaką można dodać, aby wymusić przesunięcie, jednocześnie zapewniając, że dodana wartość nigdy nie zmienia zaokrąglenia, nawet jeśli .brakuje dziesiętnego . Mógłbym użyć tylko 10**(-len(val))warunku, if (val>1)aby odjąć 1więcej ... ale łatwiej jest po prostu zawsze odjąć, 1ponieważ nie zmieni to zbytnio odpowiedniego zakresu liczb dziesiętnych, które to obejście może poprawnie obsłużyć. To podejście zakończy się niepowodzeniem, jeśli twoje wartości osiągną granice danego typu, to się nie powiedzie, ale dla prawie całego zakresu prawidłowych wartości dziesiętnych powinno działać.

Tak więc gotowy kod będzie podobny do:

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()

... powinien dać oczekiwane rezultaty.

Aby to zrobić, możesz również użyć biblioteki dziesiętnej , ale proponuję opakowanie jest prostsze i może być preferowane w niektórych przypadkach.


Edit: Dzięki Blckknght dla wskazując, że 5sprawa frędzle występuje tylko dla pewnych wartości tutaj .

Jason R. Mick
źródło
6

Wystarczy użyć formatowania z% .2f, co daje zaokrąglenie w dół do 2 miejsc po przecinku.

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer
Santosh Ghimire
źródło
4

Możesz użyć operatora formatowania łańcucha w pythonie „%”. „% .2f” oznacza 2 cyfry po przecinku.

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

arieli
źródło
4

Można użyć operatora okrągłego z dokładnością do 2 miejsc po przecinku

num = round(343.5544, 2)
print(num) // output is 343.55
Asad Manzoor
źródło
3

Możesz użyć funkcji okrągłej.

round(80.23456, 3)

da ci odpowiedź 80.234

W twoim przypadku użyj

answer = str(round(answer, 2))
Satyaki Sanyal
źródło
2

Jeśli chcesz uniknąć problemu z liczbą zmiennoprzecinkową przy zaokrąglaniu liczb do rozliczania, możesz użyć rundy numpy.

Musisz zainstalować numpy:

pip install numpy

i kod:

import numpy as np

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

odciski

2.67
2.68

Powinieneś tego użyć, jeśli zarządzasz pieniędzmi za pomocą legalnego zaokrąglania.

Samuel Dauzon
źródło
1

Oto przykład, którego użyłem:

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)
Patrick Hill
źródło
1

Nie jestem pewien dlaczego, ale format „{: 0.2f}” (0,5357706) daje mi „0,54”. Jedyne rozwiązanie, które działa dla mnie (python 3.6), jest następujące:

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
Noam Peled
źródło
Jest to obcinanie, a nie zaokrąglanie.
ShadowRanger