views:

656

answers:

5

I have found that the same mod operation produces different results depending on what language is being used.

In Python:

-1 % 10

produces 9

In C it produces -1 !

1) Which one is the right modulo?
2) How to make mod operation in C to be the same like in Python?

Thank you in advance!

A: 

The correct answer is the one Python gives; unfortunately, C doesn't handle negative modulos.

mipadi
That's utter BS. C99 handles the '%' operator in a well-defined manner, it's just been defined to something different from Python. See AndreyT's answer.
DevSolar
Not BS from a mathematical standpoint: modulus arithmetic has a well-defined meaning in math, and C's modulo operator doesn't handle negative numbers the way it *should*, from a mathematical perspective. The C99 has its own definition that is nonstandard w.r.t. mathematics.
mipadi
C doesn't *have* a modulo operator; the standard clearly refers to it as a *remainder* operator, and its handling of negative values is well-defined. There is nothing "incorrect" about it, and "C doesn't handle negative modulos" is BS.
DevSolar
+4  A: 

Both answers are correct since -1 modulo 10 is the same as 9 modulo 10.

r = (a mod m)
a = n*q + r

You can be sure that |r| < |n|, but not what the value of r is. There are 2 answers, negative and positive.


In C89, although the answer will always be correct, the exact value of a modulo operation (they refer to it as remainder) is undefined, meaning it can be either a negative result or a positive result. In C99 the result is defined.

If you want the positive answer though, you can simply add 10 if you find your answer is negative.

To get the modulo operator to work the same on all languages, just remember that:

n mod M == (n + M) mod M

and in general:

n mod M == (n + X * M) mod M
Brian R. Bondy
Modulo of negative numbers in C **is** defined: by the following statement: *If the quotient `a/b` is representable, the expression `(a/b)*b + a%b` shall equal `a`.*
caf
(I should add that in C `%` isn't actually defined as a "modulo" operator - it's defined as a "remainder").
caf
It seems so, I was going by this wikipedia page which states that it is not defined in C89: http://en.wikipedia.org/wiki/Modulo_operation
Brian R. Bondy
its implementaion defined i.e. its either -1 or 9 but has to be one of them
jk
@jk: Thanks for clearing that up.
Brian R. Bondy
@ Brian / jk: Incorrect answer. The current standard for C is C99, not C89, and C99 does define the *remainder* operator quite well, as the Wikipedia site Brian linked does state quite clearly.
DevSolar
@DevSolar: Of course C89 is not the current standard. I just assumed (wrongly so apparently) that this aspect didn't change from C89. I re-modified my answer
Brian R. Bondy
+18  A: 
  1. Both variants are correct, however in mathematics (number theory in particular), Python's modulo is most commonly used.
  2. In C, you do ((n % M) + M) % M to get the same result as in Python. E. g. ((-1 % 10) + 10) % 10. Note, how it still works for positive integers: ((17 % 10) + 10) % 10 == 17 % 10, as well as for both variants of C implementations (positive or negative remainder).
Alex B
What aout n = - 11? I think you meant ((n % M) + M) % M
Henrik
with (-17 + 10) % 10 you are in the same problem.
yeyeyerman
Oops, corrected. Thanks.
Alex B
I must disagree with point 1, and say that in mathematics both are correct, as it defines a congruence class.
SurDin
@SurDin: you are right, I have reworded the answer.
Alex B
@Checkers not so right, in C it doesn't define a true congruence relationship since -1 % 10 != 9 % 10 and they are obviously in the same congruence class.
fortran
@fortran That's why in C you have to roll your own implementation that does define one, no?
Alex B
@Checkers I guess so... but my discrete mathematics days seem so far away now
fortran
+11  A: 

Python has a "true" modulo operation, while C has a remainder operation.

It has a direct relation with how the negative integer division is handled, i.e. rounded towards 0 or minus infinite. Python rounds towards minus infinite and C(99) towards 0, but in both languages (n/m)*m + n%m == n, so the % operator must compensate in the correct direction.

Ada is more explicit and has both, as mod and rem.

fortran
Common Lisp also has both.
Svante
+7  A: 

In C89/90 the behavior of division operator and remainder operator with negative operands is implementation-defined, meaning that depending on the implementation you can get either behavior. It is just required that the operators agree with each other: from a / b = q and a % b = r follows a = b * q + r. Use static asserts in your code to check the behavior, if it relies critically on the result.

In C99 the behavior you observe has become standard.

In fact, either behaviors have certain logic in it. The Python's behavior implements the true modulo operation. The behavior you observed is C is consistent with rounding towards 0 (it's also Fortran behavior).

One of the reasons the rounding towards 0 is preferred in C is that it is rather natural to expect the result of -a / b be the same as -(a / b). In case of true modulo behavior, -1 % 10 would evaluate to 9, meaning that -1 / 10 has to be -1. This might be seen as rather unnatural, since -(1 / 10) is 0.

AndreyT