Python
Целочисленное деление в Python: отрицательные числа и остаток
С отрицательными числами целочисленное деление в Python может удивить. Оператор // округляет результат вниз, а не просто отбрасывает дробную часть
Поэтому -7 // 3 дает -3, хотя обычное деление -7 / 3 равно примерно -2.33
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Базовый пример
print(7 // 3)
print(-7 // 3)
print(-7 % 3)
Вывод:
2
-3
2
Главная связь сохраняется:
a = b * (a // b) + (a % b)
Проверим:
a = -7
b = 3
q = a // b
r = a % b
print(q)
print(r)
print(b * q + r)
Вывод:
-3
2
-7
Почему не -2
-7 / 3 равно -2.333...
Округление вниз означает движение к меньшему числу на числовой прямой. Для положительных чисел это похоже на отбрасывание дробной части, но для отрицательных — нет
print(int(-7 / 3))
print(-7 // 3)
Вывод:
-2
-3
int() отбрасывает дробную часть в сторону нуля
// округляет вниз
Остаток при отрицательных числах
В Python остаток % связан с //
for a in [-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3]:
print(a, a // 3, a % 3)
Для положительного делителя 3 остаток будет от 0 до 2
Это удобно в задачах с циклами, календарями, индексами и группировками, но может отличаться от ожиданий, если вы пришли из другого языка
Знак делителя тоже важен
print(7 // -3)
print(7 % -3)
Вывод:
-3
-2
Остаток в Python имеет тот же знак, что и делитель, если остаток не равен нулю
Поэтому при отрицательном делителе результат тоже может казаться неожиданным
Таблица для проверки
| Выражение | Результат |
|---|---|
7 // 3 |
2 |
7 % 3 |
1 |
-7 // 3 |
-3 |
-7 % 3 |
2 |
7 // -3 |
-3 |
7 % -3 |
-2 |
Эту таблицу полезно один раз запустить в Python и проверить руками через формулу a = b * q + r
Где это важно
Нюанс с отрицательными числами важен в задачах:
- алгоритмы и олимпиады
- индексы со сдвигом
- координаты на сетке
- календарные расчеты
- циклические буферы
- перенос формул из другого языка
Если задача работает только с положительными числами, вы можете долго не замечать разницы. Но как только появляются отрицательные значения, поведение нужно проверить отдельно
Безопасная функция для проверки
def show_division(a, b):
q = a // b
r = a % b
print(f'{a} // {b} = {q}')
print(f'{a} % {b} = {r}')
print(f'{b} * {q} + {r} = {b * q + r}')
show_division(-7, 3)
Такая функция помогает быстро увидеть связь между частным и остатком
Частые ошибки
- ожидать, что
-7 // 3даст-2 - путать
int(a / b)иa // b - забывать, что знак делителя влияет на остаток
- переносить формулу из другого языка без проверки
- тестировать только положительные числа
- не проверять деление на ноль
Что читать дальше
Базовый разбор оператора
//есть в материале Целочисленное деление в Python
Для отдельного понимания
%откройте Остаток от деления в Python
В Python // округляет вниз, а не просто отбрасывает дробную часть
Для отрицательных чисел это особенно важно: -7 // 3 равно -3, а int(-7 / 3) равно -2
Остаток % связан с целочисленным делением формулой a = b * (a // b) + (a % b), поэтому эти два оператора лучше изучать вместе