Оператор modulo изменения в С++ 11?
Возможный дубликат:
Оператор С++% гарантирует
В С++ 98/03
5.6-4
Двоичный/оператор дает частное, а двоичный оператор% дает остаток от деления первого выражения на второй. Если второй операнд/или% равен нулю, поведение undefined; в противном случае (a/b) * b + a% b равно a. Если оба операнда неотрицательны, то остаток неотрицателен; если нет, то знак остаток определяется реализацией.
В С++ 11:
5.6 -4
Двоичный/оператор дает частное, а двоичный оператор% дает остаток от деления первого выражения на второй. Если второй операнд/или% равен нулю, поведение undefined. Для интегральных операндов оператор/дает алгебраическую фактор с любой дробной частью, отброшенной; 81, если частное a/b равно представимый в типе результата, (a/b) * b + a% b равен a.
Как вы видите, что реализация, определенная для бита знака, отсутствует, что с ним происходит?
Ответы
Ответ 1
Поведение %
было сжато в С++ 11 и теперь полностью определено (кроме деления на 0
).
Сочетание усечения к нулю и тождество (a/b)*b + a%b == a
означает, что a%b
всегда положительно для положительного a
и отрицательного для отрицательного a
.
Математическая причина этого заключается в следующем:
Пусть ÷
- математическое деление, а /
- деление С++.
Для любых a и b имеем a÷b = a/b + f
(где f - дробная часть), а из стандарта также имеем (a/b)*b + a%b == a
.
a/b
, как известно, усекает в сторону 0
, поэтому мы знаем, что дробная часть всегда будет положительной, если a÷b
положительна, а отрицательная - a÷b
отрицательна:
sign(f) == sign(a)*sign(b)
a÷b = a/b + f
можно переставить, чтобы дать a/b = a÷b - f
. a
можно развернуть как (a÷b)*b
:
(a/b)*b + a%b == a
= > (a÷b - f)*b+a%b == (a÷b)*b
.
Теперь левую сторону можно также развернуть:
(a÷b)*b - f*b + a%b == (a÷b)*b
a%b == f*b
Вспомним ранее, что sign(f)==sign(a)*sign(b)
, поэтому:
sign(a%b) == sign(f*b) == sign(a)*sign(b)*sign(b) == sign(a)
Ответ 2
Алгоритм говорит (a/b)*b + a%b = a
, который легче читать, если вы помните, что он truncate(a/b)*b + a%b = a
Использование алгебры a%b = a - truncate(a/b)*b
. То есть f(a,b) = a - truncate(a/b)*b
. Для каких значений f(a,b) < 0
?
Неважно, если b
отрицательно или положительно. Он отменяет себя, потому что он появляется в числителе и знаменателе. Даже если truncate(a/b) = 0
и b
отрицательны, ну, это будет отменено, когда это произведение 0
.
Следовательно, только знак a
определяет знак f(a,b)
или a%b
.