Using GCC:
printf("%i \n", -1 % (int)4);
printf("%u \n", -1 % (unsigned int)4);
Output:
-1
3
Can I rely on this behaviour across platforms? Should I explicitly define MOD and REM macros to be sure this isn't altered?
Using GCC:
printf("%i \n", -1 % (int)4);
printf("%u \n", -1 % (unsigned int)4);
Output:
-1
3
Can I rely on this behaviour across platforms? Should I explicitly define MOD and REM macros to be sure this isn't altered?
From C99 onwards the result of % is required to be rounded toward 0 as quoted by Chris Dodd.
Prior to C99 standard, % operator's behavior on negative number is implementation defined.
When integers are divided and the division is inexact, if both operands are positive the result of the
/operator is the largest integer less than the algebraic quotient and the result of the%operator is positive. If either operand is negative, whether the result of the/operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the%operator. If the quotienta/bis representable, the expression(a/b)*b + a%bshall equala.
So the result is Yes if you're targeting C99 or newer, otherwise you can't rely on that.
If you need consistent result with portability to even older C standards, you can use div or ldiv, no need to define your own MOD and REM
C99 rationale regarding div, ldiv, and lldiv functions:
Because C89 had implementation-defined semantics for division of signed integers when negative operands were involved, div and ldiv, and lldiv in C99, were invented to provide well-specified semantics for signed integer division and remainder operations.
The C99 standard says:
6.5.5 Multiplicative operators
:
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded87). If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
:
87) This is often called ‘‘truncation toward zero’’
This implies that divide always rounds towards 0, so you can rely on it.
Note that this is different from the C++03 standard.
Your second line does an unsigned divide, converting the value -1 to unsigned int before the divide. This will always be one less than a power of 2, so that is also well defined.
The modulo operator (%) has been part of the C and C++ standards for years. I am not sure you can overload it in C++. So YES you can rely on it.