Оператор Modulo с отрицательными значениями
Почему такие операции:
std::cout << (-7 % 3) << std::endl;
std::cout << (7 % -3) << std::endl;
дают разные результаты?
-1
1
Ответы
Ответ 1
Из ISO14882: 2011 (e) 5.6-4:
Двоичный/оператор дает частное, а двоичный оператор% дает остаток от деления первого выражения на второй. Если второй операнд/или% равен нулю, поведение undefined. Для интегральных операндов оператор/дает алгебраическое отношение с любой дробной частью, отброшенной; если фактор a/b является представимый в типе результата, (a/b) * b + a% b равен a.
Остальное - базовая математика:
(-7/3) => -2
-2 * 3 => -6
so a%b => -1
(7/-3) => -2
-2 * -3 => 6
so a%b => 1
Обратите внимание, что
Если оба операнда неотрицательны, то остаток неотрицателен; если не, знак остатка определяется реализацией.
от ISO14882: 2003 (e) больше не присутствует в ISO14882: 2011 (e)
Ответ 2
Знак в таких случаях (т.е. когда один или оба операнда отрицательны) определяется реализацией. Спектр говорит в §5.6/4 (С++ 03),
Двоичный/оператор дает частное, а бинарный оператор% дает остаток от деления первого выражения на второе. Если второй операнд/или% равен нулю, поведение undefined; в противном случае (a/b) * b + a% b равно a. Если оба операнда неотрицательны, то остаток неотрицателен; , если нет, знак остатка определяется реализацией.
Это все, что должен сказать язык, что касается С++ 03.
Ответ 3
a % b
в С++ по умолчанию:
(-7/3) => -2
-2 * 3 => -6
so a%b => -1
(7/-3) => -2
-2 * -3 => 6
so a%b => 1
в python:
-7 % 3 => 2
7 % -3 => -2
в С++ для python:
(b + (a%b)) % b