问题
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?
回答1:
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/b
is representable, the expression(a/b)*b + a%b
shall equala
.Does either ANSI C or ISO C specify what -5 % 10 should be?
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/29179337/can-i-rely-on-modulo-operator-in-c-for-negative-numbers