Hướng dẫn modulo negative numbers python

Other answers, especially the selected one have clearly answered this question quite well. But I would like to present a graphical approach that might be easier to understand as well, along with python code to perform normal mathematical modulo in python.

Show

Python Modulo for Dummies

Modulo function is a directional function that describes how much we have to move further or behind after the mathematical jumps that we take during division over our X-axis of infinite numbers. So let's say you were doing 7%3

Hướng dẫn modulo negative numbers python

So in forward direction, your answer would be +1, but in backward direction-

Hướng dẫn modulo negative numbers python

your answer would be -2. Both of which are correct mathematically.

Similarly, you would have 2 moduli for negative numbers as well. For eg: -7%3, can result both in -1 or +2 as shown -

Hướng dẫn modulo negative numbers python

Forward direction


Hướng dẫn modulo negative numbers python

Backward direction


In mathematics, we choose inward jumps, i.e. forward direction for a positive number and backward direction for negative numbers.

But in Python, we have a forward direction for all positive modulo operations. Hence, your confusion -

>>> -5 % 4 
3

>>> 5 % 4
1

Here is the python code for inward jump type modulo in python:

def newMod(a,b):
    res = a%b
    return res if not res else res-b if a<0 else res

which would give -

>>> newMod(-5,4)
-1

>>> newMod(5,4)
1

Many people would oppose the inward jump method, but my personal opinion is, that this one is better!!

View Discussion

Improve Article

Save Article

  • Read
  • Discuss
  • View Discussion

    Improve Article

    Save Article

    Taking modulo of a negative number is a bit more complex mathematics which is done behind the program of Python. If we don’t understand the mathematics behind the modulo of negative number than it will become a huge blender.
     

    Mathematics behind the negative modulo :

    Let’s Consider an example, where we want to find the -5mod4 i.e. -5%4. You all must be wondering that the answer will be according to the below rule – 

    -5/4 = 1.25 
    and
    math.floor(-1.25) = -2

    But this is not the answer we get, when we’ll run the above code we’ll get the answer as 3. This is because Python’s modulo operator (%) always return a number having the same sign as the denominator. What happens behind the scene is that Python applies the distribute law of Modulo operator which is – 

    (a+b)mod n = [(a mod n)+(b mod n)]mod n

    To apply this math Python break the given statement as – 

    -5%4 = (-2*4 + 3) % 4 = 3

    This was done so that the (-2*4)%4 will give the answer as 0 (as we are always getting a multiple of divisor as our first number) and the overall result will be 3. Let’s see more examples for better understanding.

    Examples:

    -3 % 7 = ( -1*7 + 4 ) % 7 = 4 
    -5 % 2 = (-3*2 + 1) % 2 = 1

    Example #1 : 
    In this example we can see that by using this mathematics, we are able to perform and understand the negative modulo.
     

    Python3

    res1 = -5 % 4

    res2 = ((-2*4) + 3) % 4

    print(res1)

    print(res2)

    Output :

    3
    3

    Example #2 :

    Python3

    res1 = -3 % 7

    res2 = - 12 % 4

    print(res1)

    print(res2)

    Output :

    4
    0

    Have you ever wondered how it works?

    Hướng dẫn modulo negative numbers python

    Photo by the author.

    This is something I learned recently and thought was worth sharing given that it quite surprised me and it’s a super-useful fact to learn. How does Python handle the modulo operation with negative numbers? So, let’s keep it short and sweet and get straight to it.

    “The % symbol in Python is called the Modulo Operator. It returns the remainder of dividing the left hand operand by right-hand operand. It's used to get the remainder of a division problem.” —freeCodeCamp

    The basic syntax is:

    • a % b = r

    In the previous example, a is divided by b, and the r (i.e. the remainder) is returned. Let’s see an example with numbers now:

    • 7 % 2 = 1

    The result of the previous example is 1. 2 goes into 7 three times and there is 1 left over. In a similar way, if we were to choose two numbers where b > a, we would get the following:

    • 3 % 4 = 3

    This will result in 3 since 4 does not go into 3 at any time, so the original 3 remains.

    The sibling of the modulo operator is known as the integer division operation (//), where the fractional part (i.e. the remainder) is discarded. Take the following example:

    • 5 // 2 = 2

    For positive numbers, there’s no surprise. However, if one of the operands is negative, the result will be floored as well (i.e. rounded away from 0 towards negative infinity), returning the largest integer less than or equal to x. For example:

    • -5 // 2 = -3

    Now, there are several ways of performing this operation. Unlike C or C++, Python’s modulo operator always returns a number having the same sign as the denominator (divisor) and therefore the equation running on the back will be the following:

    • mod = a — math.floor(a/b) * base

    For example, working with one of our previous examples, we’d get:

    • mod = 7 — math.floor(7/2) * 2
    • mod = 7–3*2 = 1

    And the overall logic works according to the following premises:

    • a/b = q with remainder r
    • Such that: b*q + r = a and 0 <= r < b

    Now, if we want this relationship to extend to negative numbers, there are a couple of ways of handling this corner case. According to Wikipedia, in mathematical number theory, mathematicians prefer to stick to flooring towards negative infinity as in the following example:

    • -500/27 = -18.51
    • math.floor(-500/27) = -19

    Python follows the same logic. Why? According to Guido van Rossum, the creator of Python, this criterion has some interesting applications. For example, consider taking a POSIX timestamp (seconds since the start of 1970) and turning it into the time of day. Since there are 24*3600 = 86,400 seconds in a day, this calculation is simply t % 86,400. But if we were to express times before 1970 using negative numbers, other criteria used would give a meaningless result, while using the floor rule works out fine.

    Finally, take into account the following when working with negative numbers:

    • If a < 0 then 0 <= r < b remains the same.
    • But if b < 0 then 0 >= r > b.

    Finally, let’s see a quick example for a = -500 and b = 12:

    • -500/12 = -41.67
    • -500 % 12 = 4
    • -500 // 12 = -42

    Then we can check for b*q + r = a:

    • 12 * -42 + 4 = -500

    To end this article, let’s see an interesting application of the modulo operator with negative numbers: converting an hour written in the 24-hour clock into the 12-hour clock. The challenge seems easy, right? For example, 23%2 will give us 11 and 15%12 will give us 3… exactly what we want! Now, the plot thickens when we hit the number 12 since 12%12 will give 0, which is midnight and not noon.

    The solution here is using the modulo operator with negative numbers. For example, -22%12 will give us 2 and -19/12 will give us 5. As a rule of thumb, this kind of operation will always give us how many units we have left until the next multiple of our denominator. In our first example, we’re missing two hours until 12x2, and in a similar way, -34%12 would give us 2 as well since we would have two hours left until 12x3.

    So, coming back to our original challenge of converting an hour written in the 24-hour clock into the 12-hour clock, we could write the following:

    def convert24to12(hour):return 12 — ((- hour) % 12)

    That’s all for today. Don’t forget to take a look to some of my other stories on Better Programming:

    And if you want to receive my latest articles directly on your email, just subscribe to my newsletter :). See you around, and thanks for reading! Thanks for reading!