Округлить до второго знака после запятой в Python - PullRequest
43 голосов
/ 10 февраля 2012

Как мне округлить число до второго знака после запятой в питоне?Например:

0.022499999999999999

Должно округляться до 0.03

0.1111111111111000

Должно округляться до 0.12

Если в третьем знаке есть какое-либо значениеместо, я хочу, чтобы он всегда округлялся, оставляя мне 2 значения после запятой.

Ответы [ 9 ]

48 голосов
/ 10 февраля 2012

Python включает в себя функцию round(), которая позволяет вам указать желаемое количество цифр.Из документации:

round(x[, n])

Возвращает значение с плавающей запятой x, округленное до n цифр после десятичной точки.Если n опущено, по умолчанию используется ноль.Результатом является число с плавающей запятой.Значения округляются до ближайшего кратного 10 к степени минус n;если два мультипликатора одинаково близки, округление выполняется вдали от 0 (так, например, раунд (0,5) равен 1,0, а раунд (-0,5) равен -1,0).

Так что вы хотитеиспользуйте round(x, 2), чтобы сделать нормальное округление.Чтобы число всегда округлялось до , вам необходимо использовать функцию ceil(x).Аналогично, чтобы округлить вниз , используйте floor(x).

26 голосов
/ 10 февраля 2012
from math import ceil

num = 0.1111111111000
num = ceil(num * 100) / 100.0

Смотри:math.ceil документация round документация - Возможно, вы все равно захотите проверить это для дальнейшего использования

13 голосов
/ 10 февраля 2012

Экстраполируя из ответа Эдвина:

from math import ceil, floor
def float_round(num, places = 0, direction = floor):
    return direction(num * (10**places)) / float(10**places)

Для использования:

>>> float_round(0.21111, 3, ceil)  #round up
>>> 0.212
>>> float_round(0.21111, 3)        #round down
>>> 0.211
>>> float_round(0.21111, 3, round) #round naturally
>>> 0.211
11 голосов
/ 10 февраля 2012
x = math.ceil(x * 100.0) / 100.0
10 голосов
/ 15 июля 2015

Это зависит от поведения, которое вы хотите при рассмотрении положительных и отрицательных чисел, но если вы хотите, чтобы что-то всегда округлялось до большего значения (например, 2.0449 -> 2.05, -2.0449 -> -2.04), тогда вы можете сделать:

round(x + 0.005, 2)

или немного любитель:

def round_up(x, place):
    return round(x + 5 * 10**(-1 * (place + 1)), place)

Это также работает следующим образом:

round(144, -1)
# 140
round_up(144, -1)
# 150
round_up(1e308, -307)
# 1.1e308
4 голосов
/ 02 февраля 2015

Обратите внимание, что трюк ceil(num * 100) / 100 будет зависать на некоторых вырожденных входах, таких как 1e308.Это может случаться не часто, но я могу сказать, что это стоило мне пару дней.Чтобы избежать этого, «было бы неплохо, если бы» ceil() и floor() принимали аргумент с десятичными знаками, как это делает round() ... Между тем, любой знает чистую альтернативу, которая не потерпит крахна входах, как это?У меня были некоторые надежды на пакет decimal, но он, похоже, тоже умирает:

>>> from math import ceil
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP
>>> num = 0.1111111111000
>>> ceil(num * 100) / 100
0.12
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
0.12
>>> num = 1e308
>>> ceil(num * 100) / 100
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

Конечно, можно сказать, что сбой является единственным нормальным поведением на таких входах, но яЯ бы сказал, что проблема не в округлении, а в умножении (именно поэтому, например, 1e306 не дает сбоя), а более чистая реализация fn с округлением-вверх позволяет избежать взлома умножения.

2 голосов
/ 04 апреля 2018
def round_up(number, ndigits=None):
    # start by just rounding the number, as sometimes this rounds it up
    result = round(number, ndigits if ndigits else 0)
    if result < number:
        # whoops, the number was rounded down instead, so correct for that
        if ndigits:
            # use the type of number provided, e.g. float, decimal, fraction
            Numerical = type(number)
            # add the digit 1 in the correct decimal place
            result += Numerical(10) ** -ndigits
            # may need to be tweaked slightly if the addition was inexact
            result = round(result, ndigits)
        else:
            result += 1 # same as 10 ** -0 for precision of zero digits
    return result

assert round_up(0.022499999999999999, 2) == 0.03
assert round_up(0.1111111111111000, 2) == 0.12

assert round_up(1.11, 2) == 1.11
assert round_up(1e308, 2) == 1e308
0 голосов
/ 10 марта 2019

Функция python round может быть округлена не так, как вы ожидали.

Вы можете более точно указать метод округления, используя Decimal.quantize

например.

from decimal import Decimal, ROUND_HALF_UP
res = Decimal('0.25').quantize(Decimal('0.0'), rounding=ROUND_HALF_UP)
print(res) 
# prints 0.3

Дополнительная информация:

https://gist.github.com/jackiekazil/6201722

0 голосов
/ 30 августа 2015

Указанная круглая функция не работает для определенных целых чисел, таких как:

а = 8
круглый (а, 3)
8,0
а = 8.00
круглый (а, 3)
8,0
а = +8,000000000000000000000000
круглый (а, 3)
8,0

но работает для:

г = 400 / 3,0
г
+133,33333333333334
круглый (г, 3) * * одна тысяча двадцать два 133,333

Более того, десятичные дроби, такие как 2,675, округляются до 2,67, а не 2,68.
Лучше использовать другой метод, представленный выше.

...