Остаток зависит от того, как округляют частное

Остаток определяется не сам по себе: сначала целое число делят, а затем выбирают целое частное. Связь всегда выражается равенством a = q × b + r, где q — частное, а r — остаток. Для отрицательного a разные правила выбора q дают разные r.

Возьмём −7 и 3. В Python целочисленное деление округляет частное вниз: −7 // 3 равно −3. Тогда остаток равен 2, потому что −7 = (−3) × 3 + 2. В C и Java целочисленное деление округляет частное к нулю: частное равно −2, а остаток — −1.

Почему оба результата согласуются с делением

Оба варианта удовлетворяют исходному равенству. Различается дополнительное правило: при округлении вниз остаток при положительном делителе лежит от 0 до 2, а при округлении к нулю его знак может совпадать со знаком делимого. Поэтому слово «остаток» в коде не всегда означает математический остаток, который обычно выбирают неотрицательным.

Где это становится заметно

Разница важна, когда остаток используют для циклических индексов — например, чтобы определить позицию в списке после шага назад. Если индекс равен −1, в Python выражение −1 % 5 даёт 4, то есть последнюю позицию. В языках с остатком −1 такой результат нельзя бездумно использовать как индекс: его нужно привести к диапазону от 0 до 4. Иначе перенос одной формулы между языками способен изменить поведение программы или вызвать ошибку доступа.