Why do such operations:
std::cout << (-7 % 3) << std::endl; std::cout << (7 % -3) << std::endl; give different results?
-1 1 From ISO14882:2011(e) 5.6-4:
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.
The rest is basic math:
(-7 / 3) => -2 -2 * 3 => -6 so a % b => -1 (7 / -3) => -2 -2 * -3 => 6 so a % b => 1 Note that
If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
from ISO14882:2003(e) is no longer present in ISO14882:2011(e)
-7/3 results in -2 or -3).a % b in c++ default:
(-7 / 3) => -2 -2 * 3 => -6 so a % b => -1 (7 / -3) => -2 -2 * -3 => 6 so a % b => 1 in python:
-7 % 3 => 2 7 % -3 => -2 in c++ to python:
(b + (a % b)) % b The sign in such cases (i.e when one or both operands are negative) is implementation-defined. The spec says in §5.6/4 (C++03),
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
That is all the language has to say, as far as C++03 is concerned.
-7/3 would result in -3, but that would be in a very distant past.)b is a power of 2, it used to be possible to compute n % b as n & (b-1). The new standard requires that it be computed as n < 0 ? n | -b : n & (b-1). Likewise, n / b cannot be written as a simple shift, even on hardware that supports arithmetic shifts; instead, on such systems, an expression like n/16 (if n is an int32) must be written as n < 0 ? (n+15) >> 4 : n >> 4. Horrible standard, IMHO. Note that since non-power-of-two division is inherently slow anyway, mandating Euclidian behavior wouldn't have slowed it down much.foo /= 16 could be written as asr [dword foo],4. Under the new rules, the optimal representation requires many more instructions [perhaps mov eax,[foo] / mov ebx,eax, asr eax,31 / lsr eax,28 / add eax,ebx / asr eax,4 / mov [foo],eax] Not as slow as a divide instruction, but a lot more work than a simple shift.