Solving problem is about exposing yourself to as many situations as possible like The modulo operation on negative numbers in Python and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about The modulo operation on negative numbers in Python, which can be followed any time. Take easy to follow this discuss.
I’ve found some strange behaviour in Python regarding negative numbers:
5 % 4 3-
Could anyone explain what’s going on?
Unlike C or C++, Python’s modulo operator (
%) always return a number having the same sign as the denominator (divisor). Your expression yields 3 because
(-5) / 4 = -1.25 –> floor(-1.25) = -2
(-5) % 4 = (-2 × 4 + 3) % 4 = 3.
It is chosen over the C behavior because a nonnegative result is often more useful. An example is to compute week days. If today is Tuesday (day #2), what is the week day N days before? In Python we can compute with
return (2 - N) % 7
but in C, if N ? 3, we get a negative number which is an invalid number, and we need to manually fix it up by adding 7:
int result = (2 - N) % 7; return result < 0 ? result + 7 : result;
(See http://en.wikipedia.org/wiki/Modulo_operator for how the sign of result is determined for different languages.)
Here’s an explanation from Guido van Rossum:
Essentially, it’s so that a/b = q with remainder r preserves the relationships b*q + r = a and 0 <= r < b.
There is no one best way to handle integer division and mods with negative numbers. It would be nice if
a/b was the same magnitude and opposite sign of
(-a)/b. It would be nice if
a % b was indeed a modulo b. Since we really want
a == (a/b)*b + a%b, the first two are incompatible.
Which one to keep is a difficult question, and there are arguments for both sides. C and C++ round integer division towards zero (so
a/b == -((-a)/b)), and apparently Python doesn’t.
In python, modulo operator works like this.
mod = n - math.floor(n/base) * base
so the result is (for your case):
mod = -5 - floor(-1.25) * 4 mod = -5 - (-2*4) mod = 3
int(n/base) * basemod = n -
which results in:
mod = -5 - int(-1.25) * 4 mod = -5 - (-1*4) mod = -1
If you need more information about rounding in python, read this.
As pointed out, Python modulo makes a well-reasoned exception to the conventions of other languages.
This gives negative numbers a seamless behavior, especially when used in combination with the
// integer-divide operator, as
% modulo often is (as in math.divmod):
for n in range(-8,8): print n, n//4, n%4
-8 -2 0 -7 -2 1 -6 -2 2 -5 -2 3 -4 -1 0 -3 -1 1 -2 -1 2 -1 -1 3 0 0 0 1 0 1 2 0 2 3 0 3 4 1 0 5 1 1 6 1 2 7 1 3
%always outputs zero or positive*
//always rounds toward negative infinity
* … as long as the right operand is positive. On the other hand
11 % -10 == -9
Modulo, equivalence classes for 4:
- 0: 0, 4, 8, 12… and -4, -8, -12…
- 1: 1, 5, 9, 13… and -3, -7, -11…
- 2: 2, 6, 10… and -2, -6, -10…
- 3: 3, 7, 11… and -1, -5, -9…
Here’s a link to modulo’s behavior with negative numbers. (Yes, I googled it)
I also thought it was a strange behavior of Python. It turns out that I was not solving the division well (on paper); I was giving a value of 0 to the quotient and a value of -5 to the remainder. Terrible… I forgot the geometric representation of integers numbers. By recalling the geometry of integers given by the number line, one can get the correct values for the quotient and the remainder, and check that Python’s behavior is fine. (Although I assume that you have already resolved your concern a long time ago).
It’s also worth to mention that also the division in python is different from C:
10 y = 37x = -
in C you expect the result
what is x/y in python?
print x/y -1
and % is modulo – not the remainder! While x%y in C yields
print x%y 27
You can get both as in C
from math import trunc d = trunc(float(x)/y) print d 0
And the remainder (using the division from above):
print r -10r = x - d*y
This calculation is maybe not the fastest but it’s working for any sign combinations of x and y to achieve the same results as in C plus it avoids conditional statements.