Округление в большую сторону в Python: math.ceil и аналог // для деления

Округлить число в большую сторону в Python проще всего функцией math.ceil(): math.ceil(4.2) вернёт 5.

Для деления целых без импорта и без потери точности есть приём -(-a // b).

Ещё разбираем округление до двух знаков через Decimal, до сотен, отрицательные числа и NumPy.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2994 статьи автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3648 экспертных мнений Подписаться на Телеграм-канал
Обложка: Округление в большую сторону в Python: math.ceil и аналог // для деления

Округление в большую сторону в Python делает функция math.ceil(): math.ceil(4.2) вернёт 5, а math.ceil(-4.2) вернёт −4. Она подбирает ближайшее целое, которое больше исходного числа или равно ему, и отдаёт результат типом int.

Для деления целых чисел с округлением вверх пишите -(-a // b). Это аналог оператора //, только в обратную сторону: он обходится без импорта и не теряет точность на больших числах. Сам оператор // и другие знаки языка разобраны в статье про операторы Python, а системно язык учат на курсах по Python.

CheckroiCheckroiПодборка курсов по Python568 курсов • 51 школаСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Как округлить число в большую сторону через math.ceil

Рой за ноутбуком округляет число вверх в Python
  1. Подключите модуль в начале файла: import math.
  2. Передайте число в функцию: math.ceil(x).
  3. Сохраните результат в переменную или выведите через print().
import math

print(math.ceil(4.2))        # 5
print(math.ceil(4.0))        # 4
print(math.ceil(-4.2))       # -4
print(math.ceil(7))          # 7
print(type(math.ceil(4.2)))  # <class 'int'>

В документации модуля math ceil описан как наименьшее целое, которое больше x или равно ему. Поэтому целое число возвращается как есть, и 4.0 превращается в 4.

Функция принимает и другие числовые типы, например Decimal и Fraction. Для них Python вызывает метод __ceil__ самого объекта: math.ceil(Fraction(7, 2)) вернёт 4.

Деление с округлением в большую сторону: аналог //

Оператор // делит нацело и округляет результат вниз, к меньшему числу. Отдельного оператора для округления вверх в Python нет, поэтому пользуются одним из трёх приёмов.

Способ Пример для 7 и 2 Когда подходит
-(-a // b) 4 Целые числа с любыми знаками, основной вариант
(a + b - 1) // b 4 Только положительный делитель
math.ceil(a / b) 4 Небольшие числа и дробные значения

Почему работает -(-a // b)

Минус перед делимым переворачивает задачу. Если округлить −3,5 вниз, получится −4, а второй минус превращает −4 в 4. Так выходит округление вверх для исходных 7 и 2.

print(7 // 2)            # 3
print(-(-7 // 2))        # 4
print(-(-6 // 2))        # 3
print((7 + 2 - 1) // 2)  # 4

Когда число делится без остатка, результат остаётся прежним: 6 на 2 даёт 3. Единицу сверху «добавляет» как раз остаток, и про оператор % с отрицательными числами есть отдельная инструкция по остатку от деления.

Когда math.ceil(a / b) ошибается

По справочнику языка оператор / возвращает float даже для двух целых. У float ограниченная точность: целые больше 253 (это 9 007 199 254 740 992) он хранит точно уже не все.

import math

a = 10**17 + 1
print(math.ceil(a / 1))  # 100000000000000000
print(-(-a // 1))        # 100000000000000001

На идентификаторах и суммах в копейках такая ошибка проходит без всякого сообщения. Для целых берите -(-a // b): деление нацело оставляет результат целым, а целые в Python, как сказано в описании встроенных типов, имеют неограниченную точность.

Формула (a + b - 1) // b подводит на отрицательном делителе. Для 7 и −2 она даёт −2, а правильный ответ −3.

import math

print((7 + (-2) - 1) // -2)  # -2, ошибка
print(-(-7 // -2))           # -3
print(math.ceil(7 / -2))     # -3

Пример: сколько страниц нужно для списка

Задача из жизни: 47 товаров, по 10 на странице. Страниц нужно 5, последняя заполнится не целиком.

def ceil_div(a, b):
    return -(-a // b)

items = 47
per_page = 10
print(ceil_div(items, per_page))  # 5

Приём с двумя минусами удобно спрятать в функцию с понятным именем, как ceil_div выше. Строку ceil_div(items, per_page) коллега прочитает сразу, а над -(-items // per_page) задумается.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Как округлить в большую сторону без math

Иногда модуль math подключать не разрешают, например в учебной задаче. Тогда подойдёт один из двух вариантов.

  • -(-x // 1): тот же приём с двумя минусами и делителем 1. Для дробного x результат тоже будет дробным, 5.0 вместо 5, поэтому оберните его в int().
  • int(x) + (x > int(x)): отбросить дробную часть и прибавить единицу, если она была. Логическое True в сложении считается единицей, потому что в Python тип bool входит в целые числа.
x = 4.2
print(-(-x // 1))             # 5.0
print(int(-(-x // 1)))        # 5
print(int(x) + (x > int(x)))  # 5

x = -4.2
print(int(x) + (x > int(x)))  # -4

Второй вариант правильно работает и с отрицательными числами. Функция int() отбрасывает дробную часть в сторону нуля, для −4,2 получается −4, условие ложно, и единица не прибавляется.

Как округлить вверх до двух знаков после запятой

У math.ceil() нет параметра для знаков после запятой. Первым в голову приходит простой ход: умножить на 100, округлить и поделить обратно. На части чисел так появляется лишняя копейка.

import math

print(1.1 * 100)                   # 110.00000000000001
print(math.ceil(1.1 * 100) / 100)  # 1.11

Число 1,1 во float хранится как 1,1000000000000000888…, после умножения погрешность становится видна, и ceil округляет её вверх. Почему десятичные дроби в двоичной памяти неточны, объясняет раздел учебника Python про числа с плавающей точкой. Как вообще выглядят числа в двоичной записи, показано в разборе систем счисления в Python.

Решение: модуль decimal. Создайте число из строки и округлите методом quantize() с режимом ROUND_CEILING. В документации decimal этот режим описан как округление в сторону плюс бесконечности.

from decimal import Decimal, ROUND_CEILING

print(Decimal('1.1').quantize(Decimal('0.01'), rounding=ROUND_CEILING))    # 1.10
print(Decimal('1.101').quantize(Decimal('0.01'), rounding=ROUND_CEILING))  # 1.11
print(Decimal(1.1).quantize(Decimal('0.01'), rounding=ROUND_CEILING))      # 1.11

Кавычки в Decimal('1.1') обязательны. Без них Decimal(1.1) получит ту же неточность float и снова вернёт 1.11, это видно по третьей строке примера.

Как округлить вверх до десятков, сотен или кратного числа

Коробки с товарами, сложенные стопками по десять

Цены часто округляют до сотен, а количество упаковок до кратного пяти. Для этого число делят на шаг, округляют частное вверх и умножают обратно. В таблицах ту же задачу решает функция ОКРВВЕРХ, о ней есть отдельная инструкция по округлению в Excel.

def ceil_to(x, step):
    return -(-x // step) * step

print(ceil_to(1234, 100))  # 1300
print(ceil_to(1200, 100))  # 1200
print(ceil_to(37, 5))      # 40
print(ceil_to(-1234, 100)) # -1200

Для целых снова подходит приём с двумя минусами, он не уходит во float. Вариант math.ceil(1234 / 100) * 100 даст те же 1300, но на больших числах повторит ошибку точности из раздела про деление.

Встроенная round() с отрицательным вторым аргументом здесь не поможет. round(1234, -2) вернёт 1200: функция ищет ближайшую сотню, а ближайшая к 1234 лежит ниже.

Отрицательные числа: вверх или от нуля

math.ceil() округляет в сторону плюс бесконечности. Для −2,5 это −2: число стало больше, хотя по модулю уменьшилось.

Если нужно округлять от нуля, чтобы и 2,5, и −2,5 росли по модулю, в decimal есть режим ROUND_UP. Сравнение всех вариантов на двух числах:

Способ 2.5 −2.5
math.ceil(), ROUND_CEILING 3 −2
ROUND_UP (от нуля) 3 −3
math.floor() 2 −3
int(), math.trunc() 2 −2
from decimal import Decimal, ROUND_UP

print(Decimal('-2.5').quantize(Decimal('1'), rounding=ROUND_UP))  # -3
Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Округление вверх в NumPy

Для массивов есть np.ceil(), функция округляет каждый элемент. Массив дробных чисел она возвращает тоже дробным: 2.0 вместо 2, как в примере из справки NumPy.

import numpy as np

a = np.array([1.2, -1.2, 3.0])
print(np.ceil(a))              # [ 2. -1.  3.]
print(np.ceil(a).astype(int))  # [ 2 -1  3]

Если NumPy уже стоит в проекте для расчётов, например для суммы элементов списка, цикл с math.ceil() по массиву не нужен: np.ceil() обработает всё одной строкой.

Частые ошибки при округлении вверх

Рой радуется, что код вывел правильное число
  • round() вместо ceil. Функция round() округляет к ближайшему, а при равном расстоянии к чётному: round(2.5) вернёт 2, round(3.5) вернёт 4. Так написано в описании встроенных функций. Вверх она не округляет.
  • int() вместо ceil. int(2.9) вернёт 2: функция отбрасывает дробную часть.
  • Забыли импорт. Без строки import math вызов упадёт с NameError: name 'math' is not defined.
  • Строка вместо числа. math.ceil('3.2') выдаст TypeError: must be real number, not str. Значение из input() сначала переводят в число, как это сделать с проверкой, показано в инструкции про ввод числа в Python.
  • Бесконечность и NaN. math.ceil(float('inf')) вызывает OverflowError, а NaN даёт ValueError. Если такие значения бывают в данных, отсейте их через math.isfinite() до округления.

Где освоить Python системно

Округление вверх кажется мелочью, но на нём хорошо видно, как по-разному ведут себя int, float и Decimal. Чтобы разобраться в типах и стандартной библиотеке целиком, сравните курсы по программе, цене и отзывам выпускников.

Закрепить основы на практике помогут 30 задач по Python для начинающих с разбором.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология137 011 ₽7125 ₽/мес.21 месяцОбзор курса
ДО Профессия Python-разработчик
Перейти на сайт курса
GeekBrainsGeekBrains149 001 ₽3167 ₽/мес.10 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox118 666 ₽4108 ₽/мес.9 месяцевОбзор курса
Программирование на Python ПРО
Перейти на сайт курса
SkillboxSkillbox119 600 ₽ - 17 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Какая функция в Python округляет число в большую сторону?

Функция math.ceil() из модуля math. Она возвращает ближайшее целое, которое больше числа или равно ему: math.ceil(4.2) даёт 5, math.ceil(-4.2) даёт −4.

Как разделить числа с округлением в большую сторону?

Для целых чисел пишите -(-a // b): для 7 и 2 получится 4. Приём работает без импорта, с любыми знаками и не теряет точность на больших числах, в отличие от math.ceil(a / b).

Как округлить в большую сторону в питоне без math?

Подойдёт int(x) + (x > int(x)): функция int() отбрасывает дробную часть, а сравнение добавляет единицу, если дробная часть была. Для 4.2 результат 5, для −4.2 результат −4.

Почему math.ceil(-2.5) возвращает -2, а не -3?

ceil округляет в сторону плюс бесконечности, а −2 больше −2,5. Если нужно округление от нуля, используйте Decimal с режимом ROUND_UP: он превратит −2,5 в −3.

Как округлить в большую сторону до двух знаков после запятой?

Надёжнее всего через decimal: Decimal('1.101').quantize(Decimal('0.01'), rounding=ROUND_CEILING) вернёт 1.11. Вариант math.ceil(x * 100) / 100 ошибается на части чисел: для 1.1 он даёт 1.11 из-за неточности float.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!