← Назад к вопросам

Результат -12 % 10 и -12 // 10

2.7 Senior🔥 221 комментариев
#Тестирование

Условие

Какой будет результат следующих операций в Python?

print(-12 % 10)
print(-12 // 10)

Задача

  1. Предскажите вывод
  2. Объясните, как работает оператор % с отрицательными числами в Python
  3. Как это отличается от других языков (C, Java)?

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Результат -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?

  1. Математическая последовательность: Floor division — стандарт в математике
  2. Периодичность: Остаток всегда в диапазоне [0, b) при положительном b
  3. Полезность для циклических операций: Модульная арифметика работает естественнее
  4. Консистентность: Один алгоритм для всех комбинаций знаков

Сравнение языков

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?
  • Как использовать модуль для циклических структур данных?