Округлення до двох знаків після коми у Python 2.7?


84

Використовуючи Python 2.7, як я можу округлити мої числа до двох знаків після коми, а не до числа 10, яке воно дає?

print "financial return of outcome 1 =","$"+str(out1)

3
Це може бути консервна банка. Ви зберігаєте фінансові дані у змінній із плаваючою комою і тепер хочете округлити це? Точне округлення в більшості випадків неможливе. Можливо, ви захочете використовувати цілі чи Decimals, залежно від того, що ви насправді намагаєтесь зробити.
Тім Пітцкер,

Дізнайтеся про специфікатори формату. Ви можете безпосередньо друкувати плаваючі значення, не перетворюючи їх у рядки.
John Doe,

Відповіді:


201

Використовуйте вбудовану функцію round():

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

Або вбудована функція format():

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

Або новий стиль форматування рядків:

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

Або форматування рядків старого стилю:

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

довідка щодо 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.

2
Метод форматування рядків корисний при роботі з десятковими кодами. Напр.Decimal("{:.2f}".format(val))
Патч Рік Уолш

@PatchRickWalsh Або просто Decimal(format(val, '.2f')).
Ашвіні Чаудхарі,

9
Класно! Я не знав про вбудований формат. Після вивчення більшого, я думаю, це найточніший спосіб округлення, якщо помилки з плаваючою комою абсолютно неприйнятні: Decimal('123.345').quantize(Decimal('1.00'), rounding=decimal.ROUND_HALF_UP)дає вам Decimal('123.35'). З іншого боку, це Decimal(format(Decimal('123.345'), '.2f'))дає вам, Decimal('123.34')оскільки двійкове представлення 123.345 менше 123.345.
Патч Рік Уолш

48

Оскільки ви говорите про фінансові показники, ви НЕ ХОЧЕТЕ використовувати арифметику з плаваючою комою. Вам краще використовувати Decimal.

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

Форматування виводу тексту в новому стилі format()(за замовчуванням округлення з половиною парних розмірів):

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

Подивіться відмінності в округленні через неточність із плаваючою точкою:

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

Правильний спосіб округлення фінансових цінностей :

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

Також часто зустрічаються інші типи округлення в різних операціях:

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

Пам’ятайте, що якщо ви імітуєте результат повернення, вам, можливо, доведеться округляти кожен процентний період, оскільки ви не можете сплатити / отримати центові фракції, ні отримати відсотки над центними частками. Для моделювання досить часто просто використовувати плаваючу крапку через властиві невизначеності, але, роблячи це, завжди пам’ятайте, що помилка є. Таким чином, навіть інвестиції з фіксованими відсотками можуть дещо відрізнятися у прибутковості через це.



4

При роботі з копійками / цілими числами. Ви зіткнетеся з проблемою з 115 (як у $ 1,15) та іншими номерами.

У мене була функція, яка перетворює ціле число на плаваючий.

...
return float(115 * 0.01)

Це спрацьовувало більшу частину часу, але іноді це повертало щось подібне 1.1500000000000001.

Тож я змінив свою функцію повернення таким чином ...

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

і це повернеться 1.15. Ні '1.15'або 1.1500000000000001(повертає плаваючу, а не рядок)

Я в основному публікую це, щоб я міг згадати, що я робив за цим сценарієм, оскільки це перший результат у google.


Як зазначено в іншій відповіді, для фінансових даних використовуйте десяткові числа, а не плаваючі числа.
Бруно Ле Флох,

1
У підсумку я перетворив майже все на цілі числа. Здається, набагато простіше працювати. Однак я не робив нічого, що стосується частки копійки.
teewuane

2

Найкращим, на мою думку, є використання функції format () :

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

Але я повинен сказати: не використовуйте раунд або форматування, працюючи з фінансовими цінностями.


formatвимагає нестрокового для формату f. Якщо ні, ви отримали ValueError. Правильний код: format(out1, '.2f')без
приведення

2

Коли ми використовуємо функцію round (), вона не дасть правильних значень.

Ви можете перевірити це, використовуючи круглі (2.735) та круглі (2.725)

будь ласка, використовуйте

import math
num = input('Enter a number')
print(math.ceil(num*100)/100)

Будь ласка, додайте приклад, який ви перевірили, результати та, на вашу думку, що з ними неправильно.
Ліран Фунаро,

import math num = input ('Enter a number') numr = float (round (num, 2)) print numr
Midhun MM


0

Досить простим обхідним шляхом є перетворення спочатку float у рядок, вибір підрядка з перших чотирьох чисел, нарешті, перетворення підрядка назад у float. Наприклад:

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

Може бути не супер ефективним, але простим і працює :)


2
Цей метод дуже ненадійний. Якщо у вашому значенні є більше однієї цифри перед десятковою комою, ви не отримаєте двох потрібних знаків після коми. Та сама проблема з від’ємним числом.
Андре Кульманн,

0

Округлюючи до наступної 0,05, я б зробив так:

def roundup(x):
    return round(int(math.ceil(x / 0.05)) * 0.05,2)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.