Методы округления чисел в Python

Иван Корнев·21.05.2024·3 мин

Чтобы округлить число в Python до ближайшего целого, используйте встроенную функцию round(). Для принудительного округления вверх или вниз подключите модуль math и примените функции ceil() и floor(). Если требуется строгое арифметическое округление (например, 2.5 → 3), используйте класс Decimal из стандартной библиотеки, так как стандартный round() применяет банковское правило (до ближайшего четного).

Базовое округление функцией round()

Функция round(number[, ndigits]) возвращает число, округленное до указанного количества знаков после запятой. Если второй параметр опущен, результат приводится к ближайшему целому.

Важная особенность Python 3: при дробной части ровно 0.5 используется банковское округление (round half to even). Число округляется до ближайшего четного значения. Это сделано для минимизации статистической погрешности при больших объемах вычислений.

round(3.2)   # 3
round(3.5)   # 4 (ближайшее четное)
round(2.5)   # 2 (ближайшее четное)
round(4.5)   # 4
round(-2.5)  # -2

Если нужно получить именно тип int, явно приведите результат:

int(round(3.6))  # 4

Для сохранения определенного количества знаков после запятой передайте второй аргумент:

round(3.14159, 2)  # 3.14
round(1.25, 1)     # 1.2 (так как 2 — четное)

Не используйте round() для финансовых расчетов, где критично правило «0.5 всегда вверх». Стандартное поведение может привести к потерям или расхождениям в отчетах на копейки.

Принудительное округление вверх и вниз

Когда логика задачи требует игнорировать дробную часть в конкретную сторону, используйте функции из модуля math:

  • math.floor(x) — округление вниз (к меньшему целому).
  • math.ceil(x) — округление вверх (к большему целому).

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

import math

math.floor(3.9)   # 3
math.floor(-3.1)  # -4 (меньшее число)

math.ceil(3.1)    # 4
math.ceil(-3.9)   # -3 (большее число)

Обе функции всегда возвращают тип int.

Точное арифметическое округление через Decimal

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

Наиболее частый сценарий — ROUND_HALF_UP (арифметическое округление):

from decimal import Decimal, ROUND_HALF_UP

value = Decimal('2.5')
result = value.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
# Результат: Decimal('3')

value2 = Decimal('3.5')
result2 = value2.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
# Результат: Decimal('4')

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

При создании объекта Decimal всегда передавайте число как строку (Decimal('2.5')), а не как float (Decimal(2.5)). Передача float может сразу внести ошибку представления еще до начала округления.

Сравнение методов округления

МетодФункцияПоведение при .5Возвращаемый типКогда использовать
Стандартноеround()До ближайшего четногоint или floatОбщая логика, статистика
Внизmath.floor()Всегда внизintРасчет страниц, пакетов
Вверхmath.ceil()Всегда вверхintРасчет стоимости доставки, запасов
АрифметическоеDecimalВсегда вверх (по настройке)DecimalФинансы, бухгалтерия

Частые ошибки

  1. Ожидание математического правила от round(). Программисты часто удивляются, что round(2.5) дает 2. Помните про банковское правило.
  2. Работа с плавающей точкой напрямую. Выражение round(2.675, 2) может вернуть 2.67 вместо 2.68 из-за того, что число 2.675 в памяти компьютера хранится как 2.674999.... Решение — использовать Decimal.
  3. Путаница с отрицательными числами. math.floor(-3.1) возвращает -4, а не -3, так как -4 меньше, чем -3.1.

FAQ

Как округлить число до десятков или сотен? Используйте отрицательное значение во втором аргументе round(): round(1234, -2) вернет 1200 (округление до сотен). round(1234, -1) вернет 1230 (округление до десятков).

Почему int(3.9) дает 3, а не 4? Функция int() не округляет, она отсекает дробную часть (работает как floor для положительных чисел). Для округления используйте round() или math.ceil().

Как округлить массив чисел в NumPy? Библиотека NumPy поддерживает векторизированные операции: np.round(array), np.floor(array), np.ceil(array). Они работают аналогично встроенным функциям, но применяются ко всему массиву сразу.