Как округлить up число в python?

Вещественные числа (float)

Вещественные числа поддерживают те же операции, что и целые. Однако (из-за представления чисел в компьютере) вещественные числа неточны, и это может привести к ошибкам:

>>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
0.9999999999999999

Для высокой точности используют другие объекты (например Decimal и Fraction)).

Также вещественные числа не поддерживают длинную арифметику:

>>> a = 3 ** 1000
>>> a + 0.1
Traceback (most recent call last):
  File "", line 1, in
OverflowError: int too large to convert to float

Простенькие примеры работы с числами:

>>> c = 150
>>> d = 12.9
>>> c + d
162.9
>>> p = abs(d - c)  # Модуль числа
>>> print(p)
137.1
>>> round(p)  # Округление
137

Модуль decimal

Последнее обновление: 02.05.2017

При работе с числами с плавающей точкой (то есть float) мы сталкиваемся с тем, что в результате вычислений мы получаем не совсем верный результат:

number = 0.1 + 0.1 + 0.1
print(number)       # 0.30000000000000004

Проблему может решить использование функции round(), которая округлит число. Однако есть и другой способ,
который заключается в использовании встроенного модуля decimal.

Ключевым компонентом для работы с числами в этом модуле является класс Decimal. Для его применения нам надо создать его объект
с помощью конструктора. В конструктор передается строковое значение, которое представляет число:

from decimal import Decimal

number = Decimal("0.1")

После этого объект Decimal можно использовать в арифметических операциях:

from decimal import Decimal

number = Decimal("0.1")
number = number + number + number
print(number)       # 0.3

В операциях с Decimal можно использовать целые числа:

number = Decimal("0.1")
number = number + 2

Однако нельзя смешивать в операциях дробные числа float и Decimal:

number = Decimal("0.1")
number = number + 0.1	# здесь возникнет ошибка

С помощью дополнительных знаков мы можем определить, сколько будет символов в дробной части числа:

number = Decimal("0.10")
number = 3 * number
print(number)       # 0.30

Строка «0.10» определяет два знака в дробной части, даже если последние символы будут представлять ноль. Соответственно «0.100» представляет три знака в дробной части.

Округление чисел

Объекты Decimal имеют метод quantize(), который позволяет округлять числа. В этот метод в качестве первого аргумента передается
также объект Decimal, который указывает формат округления числа:

from decimal import Decimal

number = Decimal("0.444")
number = number.quantize(Decimal("1.00"))
print(number)       # 0.44

number = Decimal("0.555678")
print(number.quantize(Decimal("1.00")))       # 0.56

number = Decimal("0.999")
print(number.quantize(Decimal("1.00")))       # 1.00

Используемая строка «1.00» указывает, что округление будет идти до двух знаков в дробной части.

По умолчанию округление описывается константой ROUND_HALF_EVEN, при котором число округляется в большую сторону, если оно нечетное, а предыдущее перед ним больше 4.
Например:

from decimal import Decimal, ROUND_HALF_EVEN


number = Decimal("10.025")
print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN))       # 10.02

number = Decimal("10.035")
print(number.quantize(Decimal("1.00"), ROUND_HALF_EVEN))       # 10.04

Стратегия округления передается в качестве второго параметра в quantize.

Строка «1.00» означает, что округление будет идти до двух чисел в дробной части. Но в первом случае «10.025» — вторым знаком идет 2 — четное число, поэтому, несмотря на то, что следующее число 5,
двойка не округляется до тройки.

Во втором случае «10.035» — вторым знаком идет 3 — нечетное число, поэтому оно округляется до 4.

Данное поведение при округлении, возможно, не всем покажется желательным, и в этом случае его можно переопределить, использовав одну из следующих констант:

  • ROUND_HALF_UP: округляет число в сторону повышения, если после него идет число 5 или выше

  • ROUND_HALF_DOWN: округляет число в сторону повышения, если после него идет число больше 5

    number = Decimal("10.026")
    print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN))       # 10.03
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_HALF_DOWN))       # 10.02
    
  • ROUND_05UP: округляет только 0 до единицы, если после него идет 5

    number = Decimal("10.005")
    print(number.quantize(Decimal("1.00"), ROUND_05UP))       # 10.01
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_05UP))       # 10.02
    
  • ROUND_CEILING: округляет число в большую сторону вне зависимости от того, какое число идет после него

    number = Decimal("10.021")
    print(number.quantize(Decimal("1.00"), ROUND_CEILING))       # 10.03
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_CEILING))       # 10.03
    
  • ROUND_FLOOR: не округляет число вне зависимости от того, какое число идет после него

    number = Decimal("10.021")
    print(number.quantize(Decimal("1.00"), ROUND_FLOOR))       # 10.02
    
    number = Decimal("10.025")
    print(number.quantize(Decimal("1.00"), ROUND_FLOOR))       # 10.02
    

НазадВперед

12 ответов

Я не знаю стандартной функции в Python, но это работает для меня:

Легко понять, почему вышесказанное работает. Вы хотите убедиться, что ваше число, деленное на 5, является целым, правильно округленным. Итак, сначала мы делаем именно это (), а затем, поскольку мы делим на 5, мы умножаем также на 5. Окончательное преобразование в происходит потому, что возвращает значение с плавающей точкой в ​​Python.

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

Для округления до нецелых значений, таких как 0,05:

Я нашел это полезным, поскольку я мог просто выполнить поиск и замену в моем коде, чтобы изменить «round (» на «myround (»), не меняя значения параметров.

Удаление ‘rest’ сработает:

Если значение является целым числом:

Как функция:

round (x ): значения округляются до ближайшего кратного 10 от степени минус n. Так что, если n отрицательно …

Поскольку 10 = 5 * 2, вы можете использовать целочисленное деление и умножение с 2, а не деление с плавающей точкой и умножение с 5,0

Не так уж это важно, если только вы не любите сдвигать биты. Извините, я хотел прокомментировать ответ Алока Сингхая, но он не позволит мне из-за отсутствия репутации = /

Извините, я хотел прокомментировать ответ Алока Сингхая, но он не позволит мне из-за отсутствия репутации = /

В любом случае, мы можем обобщить еще один шаг и идти:

Это позволяет нам использовать нецелочисленные основания, такие как или любую другую дробную базу.

Модифицированная версия divround: -)

Использование:

Он не использует умножение и не будет преобразовывать из /в числа с плавающей точкой.

Округление до ближайшего кратного 10:

Как видите, он работает как для отрицательных, так и для положительных чисел. Галстуки (например, -15 и 15) всегда будут округлены вверх.

Аналогичный пример, округляющий до ближайшего кратного 5, демонстрирующий, что он также ведет себя, как и ожидалось, для другой «базы»:

В случае, если кому-то нужно «финансовое округление» (всегда 0,5 округления вверх):

Согласно документации, другие варианты округления следующие:

По умолчанию Python использует ROUND_HALF_EVEN, поскольку он имеет некоторые статистические преимущества (округленные результаты не смещены).

Как насчет этого?

Следующий кратный 5

Учтите, что 51 нужно преобразовать в 55:

Вы можете «обмануть» для округления вместо округления путем добавления к
номер, который вы передаете .

Банковское округление в round()

Банковское (или бухгалтерское) округление позволяет уменьшить погрешности при работе с большим массивом данных. Обычное (или арифметическое) округление даёт нарастающую погрешность из-за того, что для округления в меньшую сторону на конце должны быть цифры: 1, 2, 3, 4 — всего 4 цифр, а в большую: 5, 6, 7, 8, 9 — всего 5 цифр. Неравное количество цифр при большом количестве вычислений и вызывают нарастающую погрешность.
При банковском округлении осуществляется округление к ближайшему чётному, то есть , . Таким образом вероятность того, что перед пятёркой окажется чётное или нечётное число для большинства случаев (к примеру, бухгалтерские расчёты) примерно одинаковая, поэтому такой принцип уменьшает погрешность.

Здесь вы можете увидеть подробности округления в официальных источниках документации python:

«if two multiples are equally close, rounding is done toward the even choice» (перев.: Округление делается до ближайшего четного) — это и есть банковское округление.

Но напоследок приведу пример, наглядно демонстрирующий разницу работы функции round() в различных версиях python и с учётом неточности представления типа :

Пример round() в python 2 round() в python 3 банковское округление
round(2.05, 1) 2.0 2.0 2.0
round(2.15, 1) 2.1 2.1 2.2
round(2.25, 1) 2.3 2.2 2.2
round(2.35, 1) 2.4 2.4 2.4
round(2.45, 1) 2.5 2.5 2.4
round(2.55, 1) 2.5 2.5 2.6
round(2.65, 1) 2.6 2.6 2.6
round(2.75, 1) 2.8 2.8 2.8
round(2.85, 1) 2.9 2.9 2.8
round(2.95, 1) 3.0 3.0 3.0

Жирным выделил отличающиеся значения выполнения функции round().

Казалось бы в примере с результат для python 3 должен быть , потому как python 3 работает по банковскому округлению, но правильное значение , так как значение в машинном представлении не точное и выглядит для, к примеру, 60 знаков после запятой следующим образом:

>>> '%0.60f' % 2.15
'2.149999999999999911182158029987476766109466552734375000000000'

Отсюда видно, что по правилам обычного арифметического округления получаем .

Но для примера 60 знаков после запятой выглядят следующим образом:

>>> '%0.60f' % 2.25
'2.250000000000000000000000000000000000000000000000000000000000'

Вот здесь-то и возникает спорный момент по способу округления. Так для python 2 получаем  — арифметическое округление.

А для python 3 получаем , что соответствует правилам банковского округления.

Материалы по теме:

Округление (Википедия)

Автор статьи

Права на использование материала, расположенного на этой странице https://vivazzi.pro/it/round-python/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра в теге . Использование:

Автор статьи: Мальцев АртёмСсылка на статью: https://vivazzi.pro/it/round-python/

Предыдущая статьяПример обработки formset

Следующая статьяsql перенос данных из одной таблицы в другую

Вам нужно саморазвиваться или вы хотите зарабатывать деньги?

Или вы ищите хорошие IT сервисы или книги? Сохраните свое время и взгляните на мою подборку рекомендаций, которыми постоянно пользуюсь.

Посмотреть рекомендации

Ознакомьтесь с реально работающими финансовыми инструментами

Wall Street Cash — Торговый робот на рынке Forex

Ознакомьтесь с роботом (советником), который автоматизирует торговлю на валютном рынке Forex без необходимости самому торговать. Преимущество робота в том, что вы сами контролируете свой счёт, а робот лишь по оптимизированным алгоритмам заключает сделки на куплю и продажу валют.

Подробнее о Wall Street Cash

Viva TM — Доверительное управление с использованием робота WSC

Доверительное управление Viva TM — это разработанный мною сервис по управлению вашими денежными средствами и заработку на рынке Форекс с использованием торгового робота Wall Street Cash.
Имеется возможность использовать моё доверительное управления для тех, кто не хочет или не может самостоятельно настроить робота.

Подробнее о Viva TM

Комплексные числа (complex)

В Python встроены также и комплексные числа:

>>> x = complex(1, 2)
>>> print(x)
(1+2j)
>>> y = complex(3, 4)
>>> print(y)
(3+4j)
>>> z = x + y
>>> print(x)
(1+2j)
>>> print(z)
(4+6j)
>>> z = x * y
>>> print(z)
(-5+10j)
>>> z = x  y
>>> print(z)
(0.44+0.08j)
>>> print(x.conjugate())  # Сопряжённое число
(1-2j)
>>> print(x.imag)  # Мнимая часть
2.0
>>> print(x.real)  # Действительная часть
1.0
>>> print(x > y)  # Комплексные числа нельзя сравнить
Traceback (most recent call last):
  File "", line 1, in
TypeError: unorderable types: complex() > complex()
>>> print(x == y)  # Но можно проверить на равенство
False
>>> abs(3 + 4j)  # Модуль комплексного числа
5.0
>>> pow(3 + 4j, 2)  # Возведение в степень
(-7+24j)

Также для работы с комплексными числами используется также модуль cmath.

Ссылка на основную публикацию