My friend said that there are differences between \"mod\" and \"remainder\".
If so, what are those differences in C and C++? Does \'%\' mean either \"mod\" or \"rem\
In C and C++ and many languages, %
is the remainder NOT the modulus operator.
For example in the operation -21 / 4
the integer part is -5
and the decimal part is -.25
. The remainder is the fractional part times the divisor, so our remainder is -1
. JavaScript uses the remainder operator and confirms this
console.log(-21 % 4 == -1);
The modulus operator is like you had a "clock". Imagine a circle with the values 0, 1, 2, and 3 at the 12 o'clock, 3 o'clock, 6 o'clock, and 9 o'clock positions respectively. Stepping quotient times around the clock clock-wise lands us on the result of our modulus operation, or, in our example with a negative quotient, counter-clockwise, yielding 3.
Note: Modulus is always the same sign as the divisor and remainder the same sign as the quotient. Adding the divisor and the remainder when at least one is negative yields the modulus.
There is a difference between modulus and remainder. For example:
-21
mod 4
is 3
because -21 + 4 x 6
is 3
.
But -21
divided by 4
gives -5
with a remainder of -1
.
For positive values, there is no difference.
Modulus, in modular arithmetic as you're referring, is the value left over or remaining value after arithmetic division. This is commonly known as remainder. % is formally the remainder operator in C / C++. Example:
7 % 3 = 1 // dividend % divisor = remainder
What's left for discussion is how to treat negative inputs to this % operation. Modern C and C++ produce a signed remainder value for this operation where the sign of the result always matches the dividend input without regard to the sign of the divisor input.
In mathematics the result of the modulo operation is the remainder of the Euclidean division. However, other conventions are possible. Computers and calculators have various ways of storing and representing numbers; thus their definition of the modulo operation depends on the programming language and/or the underlying hardware.
7 modulo 3 --> 1
7 modulo -3 --> -2
-7 modulo 3 --> 2
-7 modulo -3 --> -1
Does '%' mean either "mod" or "rem" in C?
In C, %
is the remainder1.
..., the result of the
/
operator is the algebraic quotient with any fractional part discarded ... (This is often called "truncation toward zero".) C11dr §6.5.5 6The operands of the
%
operator shall have integer type. C11dr §6.5.5 2The result of the
/
operator is the quotient from the division of the first operand by the second; the result of the%
operator is the remainder ... C11dr §6.5.5 5
What's the difference between “mod” and “remainder”?
C does not define "mod", such as the integer modulus function used in Euclidean division or other modulo. "Euclidean mod" differs from C's a%b
operation when a
is negative.
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
Modulo as Euclidean division
7 modulo 3 --> 1
7 modulo -3 --> 1
-7 modulo 3 --> 2
-7 modulo -3 --> 2
Candidate modulo code:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
Note about floating point: double fmod(double x, double y)
, even though called "fmod", it is not the same as Euclidean division "mod", but similar to C integer remainder:
The
fmod
functions compute the floating-point remainder ofx/y
. C11dr §7.12.10.1 2
fmod( 7, 3) --> 1.0
fmod( 7, -3) --> 1.0
fmod(-7, 3) --> -1.0
fmod(-7, -3) --> -1.0
Disambiguation: C also has a similar named function double modf(double value, double *iptr)
which breaks the argument value into integral and fractional parts, each of which has the same type and sign as the argument. This has little to do with the "mod" discussion here except name similarity.
1 Prior to C99, C's definition of %
was still the remainder from division, yet then /
allowed negative quotients to round down rather than "truncation toward zero". See Why do you get different values for integer division in C89?. Thus with some pre-C99 compilation, %
code can act just like the Euclidean division "mod". The above modulo_Euclidean()
will work with this alternate old-school remainder too.