Zaokrąglanie do dwóch miejsc po przecinku w Pythonie 2.7?

84

Jak za pomocą Pythona 2.7 zaokrąglić moje liczby do dwóch miejsc po przecinku, a nie do 10?

print "financial return of outcome 1 =","$"+str(out1)
RCN
źródło
2
To może być puszka robaków. Czy przechowujesz dane finansowe w zmiennej zmiennoprzecinkowej i chcesz to teraz zaokrąglić? W większości przypadków dokładne zaokrąglenie nie jest możliwe. Możesz użyć liczb całkowitych lub Decimals, w zależności od tego, co faktycznie próbujesz zrobić.
Tim Pietzcker,
Dowiedz się więcej o specyfikatorach formatu. Możesz bezpośrednio drukować wartości zmiennoprzecinkowe, bez konwertowania ich na łańcuchy.
John Doe,

Odpowiedzi:

201

Użyj wbudowanej funkcji round():

>>> round(1.2345,2)
1.23
>>> round(1.5145,2)
1.51
>>> round(1.679,2)
1.68

Lub funkcja wbudowana format():

>>> format(1.2345, '.2f')
'1.23'
>>> format(1.679, '.2f')
'1.68'

Lub nowe formatowanie ciągu znaków:

>>> "{:.2f}".format(1.2345)
'1.23
>>> "{:.2f}".format(1.679)
'1.68'

Lub formatowanie ciągów w starym stylu:

>>> "%.2f" % (1.679)
'1.68'

pomoc na round:

>>> print round.__doc__
round(number[, ndigits]) -> floating point number

Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number.  Precision may be negative.
Ashwini Chaudhary
źródło
2
Metoda formatowania ciągów jest przydatna podczas pracy z liczbami dziesiętnymi. Np.Decimal("{:.2f}".format(val))
Patch Rick Walsh
@PatchRickWalsh Lub po prostu Decimal(format(val, '.2f')).
Ashwini Chaudhary
9
Fajne! Nie wiedziałem o wbudowanym formacie. Po dokładniejszym zbadaniu uważam, że jest to najdokładniejszy sposób zaokrąglania, jeśli błędy zmiennoprzecinkowe są absolutnie niedopuszczalne: Decimal('123.345').quantize(Decimal('1.00'), rounding=decimal.ROUND_HALF_UP)daje Decimal('123.35'). Z drugiej strony Decimal(format(Decimal('123.345'), '.2f'))daje, Decimal('123.34')ponieważ binarna reprezentacja 123,345 jest mniejsza niż 123,345.
Patch Rick Walsh
48

Ponieważ mówisz o liczbach finansowych , NIE CHCESZ używać arytmetyki zmiennoprzecinkowej. Lepiej jest używać Decimal.

>>> from decimal import Decimal
>>> Decimal("33.505")
Decimal('33.505')

Formatowanie tekstu wyjściowego z nowym stylem format()(domyślnie zaokrąglenie w połowie równe):

>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.505")))
financial return of outcome 1 = 33.50
>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.515")))
financial return of outcome 1 = 33.52

Zobacz różnice w zaokrąglaniu spowodowane niedokładnością zmiennoprzecinkową:

>>> round(33.505, 2)
33.51
>>> round(Decimal("33.505"), 2)  # This converts back to float (wrong)
33.51
>>> Decimal(33.505)  # Don't init Decimal from floating-point
Decimal('33.50500000000000255795384873636066913604736328125')

Właściwy sposób na zaokrąglenie wartości finansowych :

>>> Decimal("33.505").quantize(Decimal("0.01"))  # Half-even rounding by default
Decimal('33.50')

Powszechne jest również stosowanie innych rodzajów zaokrąglania w różnych transakcjach:

>>> import decimal
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_DOWN)
Decimal('33.50')
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_UP)
Decimal('33.51')

Pamiętaj, że jeśli symulujesz wynik zwrotu, prawdopodobnie będziesz musiał zaokrąglać w każdym okresie odsetkowym, ponieważ nie możesz płacić / otrzymywać ułamków centowych ani otrzymywać odsetek powyżej ułamków centowych. W przypadku symulacji dość często używa się po prostu liczb zmiennoprzecinkowych z powodu nieodłącznych niepewności, ale jeśli to robisz, zawsze pamiętaj, że występuje błąd. W związku z tym nawet inwestycje o stałym oprocentowaniu mogą nieco różnić się zwrotami z tego powodu.

Ronan Paixão
źródło
5

Możesz też użyć str.format():

>>> print "financial return of outcome 1 = {:.2f}".format(1.23456)
financial return of outcome 1 = 1.23
TerryA
źródło
4

Podczas pracy z groszami / liczbami całkowitymi. Napotkasz problem z 115 (jak w 1,15 $) i innymi liczbami.

Miałem funkcję, która konwertuje liczbę całkowitą na zmiennoprzecinkową.

...
return float(115 * 0.01)

To działało przez większość czasu, ale czasami zwracało coś podobnego 1.1500000000000001.

Więc zmieniłem funkcję, aby powrócić w ten sposób ...

...
return float(format(115 * 0.01, '.2f'))

i to wróci 1.15. Not '1.15'or 1.1500000000000001(zwraca float, a nie string)

Przeważnie to publikuję, więc pamiętam, co zrobiłem w tym scenariuszu, ponieważ jest to pierwszy wynik w Google.

teewuane
źródło
Jak wskazano w innej odpowiedzi, w przypadku danych finansowych należy używać liczb dziesiętnych, a nie liczb zmiennoprzecinkowych.
Bruno Le Floch
1
Skończyło się na zamianie większości wszystkiego na liczby całkowite. Wydaje się, że praca z nim jest znacznie łatwiejsza. Jednak nie robiłem niczego, co dotyczyło ułamków groszy.
teewuane
2

Myślę, że najlepiej jest użyć funkcji format () :

>>> print("financial return of outcome 1 = $ " + format(str(out1), '.2f'))
// Should print: financial return of outcome 1 = $ 752.60

Ale muszę powiedzieć: nie używaj zaokrąglenia ani formatu podczas pracy z wartościami finansowymi.

Thiago Santos
źródło
formatwymaga wartości niebędącej ciągiem dla formatu f. Jeśli nie, masz ValueError. Prawidłowy kod to: format(out1, '.2f')bez rzutowania na string
danius
2

Kiedy używamy funkcji round (), nie poda ona prawidłowych wartości.

możesz to sprawdzić za pomocą, round (2,735) i round (2,725)

proszę użyć

import math
num = input('Enter a number')
print(math.ceil(num*100)/100)
Midhun MM
źródło
Dodaj testowany przykład, wyniki i jak myślisz, co jest z nimi nie tak.
Liran Funaro
import math num = input ('Enter a number') numr = float (round (num, 2)) print numr
Midhun MM
1
print "financial return of outcome 1 = $%.2f" % (out1)
nieznany z nazwiska
źródło
0

Dość prostym sposobem obejścia tego problemu jest najpierw przekonwertowanie zmiennej zmiennoprzecinkowej na łańcuch, wybranie podłańcucha pierwszych czterech liczb, a na koniec przekonwertowanie podciąg z powrotem na zmiennoprzecinkowy. Na przykład:

>>> out1 = 1.2345
>>> out1 = float(str(out1)[0:4])
>>> out1

Może nie być super wydajne, ale proste i działa :)

Shan Niz
źródło
2
Ta metoda jest bardzo zawodna. Jeśli twoja wartość ma więcej niż jedną cyfrę przed przecinkiem, nie otrzymasz dwóch pożądanych miejsc po przecinku. Ten sam problem z liczbą ujemną.
André Kuhlmann
0

Zaokrąglając do następnego 0,05, zrobiłbym to w ten sposób:

def roundup(x):
    return round(int(math.ceil(x / 0.05)) * 0.05,2)
Lucas VL
źródło