简体   繁体   中英

Can I rely on % (modulo) operator in C for negative numbers?

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 quotient a/b is representable, the expression (a/b)*b + a%b shall equal a .

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.

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 discarded 87) . 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM