Остаток от деления в Python: оператор %, divmod() и math.fmod()

Остаток от деления в Python даёт оператор %: 17 % 5 равно 2, а divmod() возвращает частное и остаток одной парой.

Разбираем, почему у отрицательных чисел остаток в питоне не такой, как в C, что делать с float и Decimal и как проверять чётность, кратность и последнюю цифру числа.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2964 статьи автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3618 экспертных мнений Подписаться на Телеграм-канал
Обложка: Остаток от деления в Python: оператор %, divmod() и math.fmod()

Остаток от деления в Python находит оператор %: запись 17 % 5 вернёт 2, потому что 17 = 5 × 3 + 2. Если нужны сразу частное и остаток, берите встроенную функцию divmod(17, 5), она отдаст пару (3, 2).

Главный подвох питона в отрицательных числах: -7 % 3 здесь равно 2, а не −1, как в C или JavaScript. Ниже разберём, почему так, как получить остаток «как в C» и где оператор % пригождается в обычных задачах. Остальные знаки языка собраны в отдельном разборе операторов Python с таблицей приоритетов.

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

Как найти остаток от деления в Python оператором %

Рой за ноутбуком делит число на части в Python

Оператор % ставится между двумя числами, как плюс или минус. Слева делимое, справа делитель, результат равен тому, что осталось после деления нацело.

Все примеры ниже можно запустить в интерактивном режиме интерпретатора. Если Python на компьютере ещё нет, начните с инструкции, как скачать и установить Python.

print(17 % 5)
print(10 % 2)
print(3 % 7)
print(17 // 5)
2
0
3
3

Последняя строка показывает соседа %, оператор //. Он даёт целую часть от деления, то есть частное без дробной части. Когда делимое меньше делителя, как в 3 % 7, частное равно нулю, а остаток совпадает с самим делимым.

Эти два оператора связаны одной формулой, которую справочник языка Python приводит дословно: x == (x // y) * y + (x % y). Проверить её можно в две строки:

a, b = 17, 5
q = a // b
r = a % b
print(q, r)
print(q * b + r == a)
3 2
True

Сокращённая запись и приоритет

У оператора есть составная форма %=: она берёт остаток и сразу записывает его в ту же переменную. Приоритет у % такой же, как у умножения и деления, поэтому сложение без скобок выполнится позже.

x = 47
x %= 10
print(x)
print(10 + 7 % 4)
print((10 + 7) % 4)
7
13
1

В выражении 10 + 7 % 4 питон сначала посчитал 7 % 4 = 3, а потом прибавил 10. Нужен остаток от суммы, ставьте скобки.

Частное и остаток сразу: функция divmod()

divmod(a, b) возвращает кортеж из двух чисел. Для целых это то же самое, что (a // b, a % b), только записано короче и считается одним вызовом. Так описывает функцию документация встроенных функций.

Самый частый случай, перевод секунд в часы, минуты и секунды:

print(divmod(17, 5))
seconds = 3725
minutes, sec = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
print(f"{hours} ч {minutes} мин {sec} с")
(3, 2)
1 ч 2 мин 5 с

Без divmod пришлось бы писать четыре строки с // и % и следить, чтобы делитель везде был один. Кортеж удобно распаковывать сразу в две переменные, как в примере.

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

Остаток от деления отрицательного числа

Числовая прямая с отрицательными числами и шагами деления

Здесь Python ведёт себя не так, как большинство языков. По правилу из справочника знак остатка совпадает со знаком делителя, а по модулю остаток всегда меньше делителя.

print(-7 % 3)
print(7 % -3)
print(-7 % -3)
print(-7 // 3)
2
-2
-1
-3

Причина в том, что // в питоне округляет вниз, к минус бесконечности, а не просто отбрасывает дробную часть. −7 / 3 = −2,33, вниз это −3. Тогда остаток равен −7 − (−3 × 3) = 2, и формула из первого раздела снова сходится.

В C и JavaScript деление округляется к нулю, и остаток там получает знак делимого. Для JavaScript это прямо записано в англоязычной справке MDN по оператору остатка. Тот же пример там даёт другой ответ:

Выражение Python C, JavaScript
-7 % 3 2 -1
7 % -3 -2 1
7 % 3 1 1

На положительных числах разницы нет. Как эти операторы устроены в C и почему там остаток берёт знак делимого, мы разбирали в статье про операторы и выражения в C.

Как получить остаток «как в C»

Такая задача возникает, когда Python-разработчик переносит алгоритм из другого языка и ему нужен знак делимого. Для этого есть math.fmod(). По документации модуля math результат fmod имеет знак первого аргумента, а не второго.

import math
print(math.fmod(-7, 3))
print(math.fmod(7, -3))
print(-7 % 3)
-1.0
1.0
2

Обратите внимание: fmod всегда возвращает float, даже на целых числах.

Дробные числа: float, fmod и Decimal

Оператор % работает и с float. С «круглыми» дробями всё предсказуемо, а вот десятичные вроде 0,1 в двоичном виде хранятся неточно, и остаток получается с хвостом.

print(7.5 % 2)
print(3.14 % 0.7)
print(1 % 0.1)
print(0.3 % 0.1)
1.5
0.3400000000000003
0.09999999999999995
0.09999999999999998

По математике 0.3 % 0.1 должно быть 0. Питон отдаёт почти 0,1, потому что 0,3 в памяти чуть меньше трёх десятых. Проверка 0.3 % 0.1 == 0 вернёт False, и условие кратности на дробях сломается без единой ошибки.

Разобраться в типах данных с преподавателем, а не по справке, помогут онлайн-курсы по Python: в каталоге у каждой программы есть цена и состав модулей.

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

Способ Знак результата Когда брать
a % b как у делителя целые числа, почти всегда
math.fmod(a, b) как у делимого float и перенос кода из C
math.remainder(a, b) любой, по модулю не больше половины делителя расчёты по стандарту IEEE 754
Decimal(a) % Decimal(b) как у делимого деньги и точные десятичные дроби

math.remainder() добавлен в Python 3.7 и считает остаток от ближайшего целого частного, а не от округлённого вниз. Поэтому remainder(8, 3) равен −1: 8 ближе к 9, чем к 6. С модулем decimal хвост пропадает, но знак у остатка берётся от делимого, как в C.

import math
from decimal import Decimal
print(math.remainder(7, 3))
print(math.remainder(8, 3))
print(Decimal("1") % Decimal("0.1"))
print(Decimal(-7) % Decimal(3))
1.0
-1.0
0.0
-1

Где оператор % нужен на практике

Рой радостно раскладывает карточки дней недели по кругу

Сам по себе оператор скучный. Интересно то, сколько учебных и рабочих задач он закрывает в одну строку. Большая часть задач по Python для начинающих так или иначе упирается в %.

Чётность и кратность числа

Число чётное, если остаток от деления на 2 равен нулю. Так же проверяется кратность любому числу: n % k == 0.

for n in (14, 15):
    if n % 2 == 0:
        print(n, "чётное")
    else:
        print(n, "нечётное")
print(2026 % 4 == 0)
print(45 % 15 == 0)
14 чётное
15 нечётное
False
True

Короткую проверку чётности удобно записывать тернарным оператором: "чётное" if n % 2 == 0 else "нечётное".

Классическая задача на кратность, FizzBuzz, решается тремя проверками. Порядок важен: сначала кратность 15, иначе до неё не дойдёт.

for n in range(1, 16):
    if n % 15 == 0:
        print("FizzBuzz")
    elif n % 3 == 0:
        print("Fizz")
    elif n % 5 == 0:
        print("Buzz")
    else:
        print(n)

На 3, 6, 9 и 12 программа печатает Fizz, на 5 и 10 Buzz, на 15 FizzBuzz, на остальных само число.

Последняя цифра и сумма цифр

Остаток от деления на 10 даёт последнюю цифру числа, на 100 две последние. Если в цикле отрезать цифры по одной, получится сумма цифр. Это работа для цикла while:

n = 2026
print(n % 10)
print(n % 100)
total = 0
while n > 0:
    total += n % 10
    n //= 10
print(total)
6
26
10

Движение по кругу

Когда индекс должен вернуться к началу списка, остаток избавляет от лишних if. Какой день недели будет через 10 дней после пятницы:

days = ["пн", "вт", "ср", "чт", "пт", "сб", "вс"]
today = 4
print(days[(today + 10) % 7])
пн

Тот же приём крутит слайды в карусели, раздаёт задачи по сотрудникам и рисует строки таблицы через одну.

Действие на каждом N-м шаге

В длинном цикле прогресс выводят по остатку, чтобы не печатать тысячу строк:

for i in range(1, 1001):
    if i % 250 == 0:
        print("обработано", i)
обработано 250
обработано 500
обработано 750
обработано 1000

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

Четыре ситуации, которые чаще всего встречаются у новичков. У каждой есть узнаваемый симптом.

  1. Деление на ноль. 10 % 0 и 10.0 % 0 падают с ZeroDivisionError (в Python 3.14 с текстом division by zero, в 3.13 и раньше текст другой, например integer modulo by zero и float modulo). Решение: проверить делитель до операции или поймать исключение через try.
  2. Строка вместо числа. input() возвращает строку, и "17" % 5 даёт TypeError: not all arguments converted during string formatting. Сообщение странное, потому что у строк % означает старое форматирование вроде "Остаток: %d" % 2. Решение: int(input()).
  3. Сравнение дробного остатка с нулём. 0.3 % 0.1 == 0 даёт False. Решение: Decimal или math.isclose(), а лучше перейти к целым, например к копейкам вместо рублей.
  4. Ожидание знака как в C. Код из учебника по другому языку на отрицательных числах выдаёт другой ответ. Решение: math.fmod() или явная проверка знака.

Ошибка с приоритетом в этот список не попала, хотя встречается тоже: a + b % c считает остаток только от b. Если сомневаетесь, ставьте скобки, их лишняя пара никому не мешает.

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

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

Остаток от деления закрывается за пять минут. Чтобы писать на Python программы, а не отдельные строки, нужны типы данных, функции, работа с файлами и библиотеками. Начать можно с пяти простых примеров кода, а дальше идти по программе курса.

Если думаете о работе разработчиком, посмотрите план, как стать 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

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

Как найти остаток от деления в питоне?

Оператором %: 17 % 5 вернёт 2. Слева делимое, справа делитель, результат можно сразу записать в переменную: r = a % b.

Чем % отличается от // в Python?

// даёт целую часть от деления, % даёт остаток. Для 17 и 5 это 3 и 2, и всегда выполняется равенство (a // b) * b + a % b == a.

Почему -7 % 3 в Python равно 2, а не -1?

В Python знак остатка совпадает со знаком делителя, потому что // округляет вниз, к минус бесконечности. В C и JavaScript остаток берёт знак делимого. Нужен такой же результат в питоне — используйте math.fmod(-7, 3), он вернёт -1.0.

Как проверить, что число делится без остатка?

Сравнить остаток с нулём: n % k == 0. Для чётности это n % 2 == 0. Больше примеров с условиями и циклами в подборке задач по Python для начинающих.

Как получить частное и остаток одновременно?

Функцией divmod(a, b): divmod(17, 5) вернёт кортеж (3, 2). Его удобно распаковать в две переменные: q, r = divmod(17, 5).

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

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

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