Результат -12 % 10 и -12 // 10
Условие
Какой будет результат следующих операций в Python?
print(-12 % 10)
print(-12 // 10)
Задача
- Предскажите вывод
- Объясните, как работает оператор % с отрицательными числами в Python
- Как это отличается от других языков (C, Java)?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Результат -12 % 10 и -12 // 10
Это вопрос о том, как Python обрабатывает операции модуля и целочисленного деления с отрицательными числами. Результаты часто удивляют разработчиков, пришедших из других языков!
Правильный ответ
При выполнении:
print(-12 % 10) # 8
print(-12 // 10) # -2
Результаты:
-12 % 10= 8-12 // 10= -2
Объяснение
После того, как // (целочисленное деление) вычисляет результат, Python обеспечивает инвариант:
a = (a // b) * b + (a % b)
Для -12 % 10 и -12 // 10:
# Сначала вычисляем целочисленное деление
-12 // 10 = -2 # Python округляет ВНИЗ (вниз по оси чисел), не к нулю!
# Затем вычисляем остаток из инварианта
-12 = (-2) * 10 + remainder
-12 = -20 + remainder
remainder = 8
# Проверка: -12 = (-2) * 10 + 8 = -20 + 8 = -12
Ключевое отличие: Floor Division
Python использует floor division (округление вниз), а не truncation (усечение в сторону нуля):
# Python (Floor Division)
print(-12 // 10) # -2 (округлили вниз)
print(-12 % 10) # 8
# C/Java (Truncation — усечение к нулю)
# -12 / 10 = -1.2
# Они бы получили: -12 // 10 = -1, -12 % 10 = -2
Визуально на числовой оси
... -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 ...
^
-12 / 10 = -1.2
Python округляет ВНИЗ: -2 (floor division)
C/Java округляют К НУЛЮ: -1 (truncation)
Различные примеры
# Положительные числа (одинаково везде)
print(12 % 10) # 2
print(12 // 10) # 1
# Отрицательное делимое (Python vs C/Java)
print(-12 % 10) # 8 (Python) vs -2 (C/Java)
print(-12 // 10) # -2 (Python) vs -1 (C/Java)
# Отрицательный делитель
print(12 % -10) # -8
print(12 // -10) # -2
# Оба отрицательные
print(-12 % -10) # -2
print(-12 // -10) # 1
Формальное объяснение
Python гарантирует, что для любых a и b (b не равно 0):
a = (a // b) * b + (a % b)
И остаток (a % b) всегда имеет тот же знак, что и делитель (или ноль):
# Знак остатка совпадает со знаком делителя
print(-12 % 10) # 8 (положительный, как 10)
print(-12 % -10) # -2 (отрицательный, как -10)
print(12 % -10) # -8 (отрицательный, как -10)
Почему Python выбрал Floor Division?
- Математическая последовательность: Floor division — стандарт в математике
- Периодичность: Остаток всегда в диапазоне [0, b) при положительном b
- Полезность для циклических операций: Модульная арифметика работает естественнее
- Консистентность: Один алгоритм для всех комбинаций знаков
Сравнение языков
Python использует Floor Division, в то время как C и Java используют Truncation (усечение к нулю).
# Python: -12 % 10 = 8, -12 // 10 = -2
# C/Java: -12 % 10 = -2, -12 / 10 = -1
Практические примеры использования
1. Циклирование по массиву
def circular_index(index, size):
return index % size
arr = [1, 2, 3, 4, 5]
print(arr[-2 % 5]) # arr[3] = 4
2. Определение чётности
print(-5 % 2) # 1 (нечётное)
print(-4 % 2) # 0 (чётное)
3. Проверка дня недели
def days_until_next_monday(current_day):
days_offset = (0 - current_day) % 7
return days_offset if days_offset > 0 else 7
print(days_until_next_monday(-1)) # 1
print(days_until_next_monday(3)) # 4
Как запомнить
Мнемоника: Python выстраивается в очередь
- // — выстраивает вниз (floor)
- % — остаток всегда в порядке (согласуется с делителем)
# Думай так:
-12 разделить на 10:
- Сколько полных десяток? -2 целых десяток (ниже -12)
- Остаток? 8 (чтобы вернуться: -20 + 8 = -12)
Проверка с кодом
a, b = -12, 10
quotient = a // b
remainder = a % b
assert a == quotient * b + remainder
print(f"{a} = {quotient} * {b} + {remainder}")
# -12 = -2 * 10 + 8
if b > 0:
assert 0 <= remainder < b
else:
assert b < remainder <= 0
Что спросит интервьюер
- Почему результат 8, а не -2?
- Как это работает с положительными делимыми?
- Зачем нужен инвариант a = (a // b) * b + (a % b)?
- Как Python отличается от C/Java?
- Как использовать модуль для циклических структур данных?