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/b
is representable, the expression(a/b)*b + a%b
shall 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.
(unsigned int)
cast will convert ALL the other constants to unsigned ints, and the -1
s will become large positive integers (one less than a power of 2) –
Ironworks %
, and most implementations were aligned even though the standard allowed more flexibility. –
Gayomart -1 % (unsigned int)4
will always be rendered as 4294967295
and then calculated % 4
and this is true across all C compilers? –
Bohman %4U
, that makes no difference.) –
Gayomart unsigned int
is 32 bits, yes. –
Ironworks %
operator behavior are introduced into C. C++03 still has the remainder result implementation defined (en.wikipedia.org/wiki/Modulo_operation and en.cppreference.com/w/cpp/numeric/math/div) –
Charge -std=c99
because some compilers don't enable C99 by default. And this won't work on older compilers –
Charge -19 % (unsigned int)23
will hardly give a useful result. –
Bohman 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 operator or not. And you can't overload any operators in C. He asked for the behavior for negative numbers –
Charge © 2022 - 2024 — McMap. All rights reserved.