Python allows a third argument in the built-in function pow that basically computes the exponentiation modulo this third argument (pow(a,b,c) = a**b % c).
How does it work when the exponent is negative? E.g.:
pow(6, -2, 13)
#-> 4
pow(6, -2, 12)
#-> Traceback (most recent call last):
#-> File "<stdin>", line 1, in <module>
#-> ValueError: base is not invertible for the given modulus
From the python built-in functions documentation:
For int operands base and exp, if mod is present, mod must also be of integer type and mod must be nonzero. If mod is present and exp is negative, base must be relatively prime to mod. In that case, pow(inv_base, -exp, mod) is returned, where inv_base is an inverse to base modulo mod.
which means that in your example, python calculates the inverse of 6 (so that 6 * inverse = 1) and calculates pow(inverse, 2, 13). In this case the inverse of 6 mod 13 is 11 (6 * 11 = 66 = 1 mod 13) and you calculate 11 ** 2 = 121 = 4 mod 13.
I think nobody answered your exact question. pow(6, -2, 13) is six to the minus second power modulo 13, that is, something (from range(13)) that gives 1 when multiplied with 6 squared. That is 4, because 4 * 6**2 == 144, which is 1 modulo 13.
The same thing modulo 12 doesn't exist, since whatever you multiply by 36 will be divisible by 12, so you'll always get 0 (and never 1) mod 12.
When the second argument is -1, it calculates the modular inverse of a (mod c). Using other negative powers -n will return the modular inverse to the n-th power (mod c).
https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
Have you tried to check it out for yourself? Python used to not support negative exponents when the third argument was supplied, something they changed in version 3.8.x, and now what it does is allow you to compute the modular inverse (as opposed to the 'standard' inverse when dealing with the reals).
So, if example pow(2, -1, 3) would tell you the inverse in mod 3 which would be 2, because 2*2 =4 = 1 mod 3
pow(base, exp) = base**exp
pow(12,2) = 144 = 12**2
Now computation of modular inverses in supported 3.8 afterwards. Before that they denied to inverse to base modulu
Related
How can I find the positive remainder of a floor division. I know I can carry out floor division with the // operator and I know I can find the remainder with % but how do I do this together
For example, the positive remainder of 12//5
The divmod() function returns (a//b, a%b) pair for input divmod(a, b)
So:
divmod(12, 5)
Would output:
(2, 2)
And this is right because 12 // 5 is 2 and 12 % 5 is also 2.
The documentation about the pow(base, exp[, mod]) function says,
"If mod is present and exp is negative, base must be relatively prime to mod. In that case, pow(inv_base, -exp, mod) is returned, where inv_base is an inverse to base modulo mod."
I don't understand the line at all and also how it works. The provided example is as follows:
>>> pow(38, -1, mod=97)
23
>>> 23 * 38 % 97 == 1
True
Shouldn't it behave like (38**-1)%97 = 0.02631578947368421 ?
If I try to go from 23 * 38 % 97 == 1 to backward, I don't know what's the inverse of modulo.
Can anyone kindly give me a clear explanation of how it ended being 23? A mathematical explanation will be highly helpful.
In modular arithmetic division does not have a unique answer, so we do not have a division operation. Instead you have modular inverses.
The docs are trying to explain that pow(b, -1, mod=m) can be used to calculate the inverse of b, modulo m. That is, finding some number d such that d * b % m = 1.
The line 23 * 38 % 97 == 1 is simply demonstrating that the answer 23, which was the result of pow(38, -1, mod=97), is the correct modular inverse of 38.
The explanation in the docs seems to be assuming the reader already has some familiarity with modular arithmetic.
Can anyone kindly give me a clear explanation of how it ended being 23? A mathematical explanation will be highly helpful.
Try running this code snippet:
for i in range(97):
s = f"{i} * 38 % 97"
print(s, "==", eval(s))
Exactly one of the lines will reveal the congruence d * 38 % 97 == 1. There are, of course, smarter ways to compute the inverse but the brute force demonstration above should make it easier to understand what a modular inverse means.
With integer arguments and mod specified, pow() does arithmetic in the "multiplicative group of integers modulo mod"
For example, the integers relatively prime to 8 (1, 3, 5, and 7) form a group under multiplication mod 8. The identity is 1. Since 3*3 = 9 is congruent to 1 modulo 8, 3 is its own inverse in this group, and
>>> pow(3, -1, 8)
3
In the doc example, 23 and 38 are inverses modulo 97.
>>> pow(23, -1, 97)
38
>>> pow(38, -1, 97)
23
This isn't particularly esoteric, but rather basic tools in number theory.
The answer from #wim and the example by #Tim Peters helps me understand what's going on in this pow() function. Let's take an example,
>>> pow(3, -1, 8)
3
Modulo by a number m must be in the range(0,m). For example 14%5 must be in range(0,5), hence it's 4.
So modulo 1/3 % 8 must be in the range(8). But as 1/3=0.33 which is not in the range, we need a way around to find it.
1/3 % 8 cannot be zero, as it's not divisible. So the lowest possible value is 1. That means, we need to represent 1/3 in such a way that x % 8 == 1 becomes True. It's obvious that 9 % 8 == 1.
As 3(target value) * 3(base) = 9, hence, the answer is 3(target value).
For a complex example, let's take:
>>> pow(38, -1, mod=97)
23
1/38=0.026. Again, need a way around. As the lowest mod should be 1, hence x % 97 == 1. Obviously 98 % 97 == 1, but 98/38 is not a whole number. Next, (2*97+1) or 195 % 97 == 1, but 195/38 is not a whole number.
In this process, (9*97+1) or 874 % 97 == 1 and 874/38=23. So the final expression becomes:
23 * 38 % 97 == 1
Hence, the answer is 23.
This question already has answers here:
How does the modulo (%) operator work on negative numbers in Python?
(12 answers)
Closed 4 years ago.
I am familiar with the usual mod result but not for negative numbers. What is the logic?
Taken from https://docs.python.org/3/reference/expressions.html
The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [1].
Looks like modulus operator always yields results with same sign as second operator.
Hence for -11 mod 5 will yield positive (4) result.
>>> -11 % 5
4
While 11 mod -5 will yield negative (-4) result.
>>> 11 % -5
-4
To find −b mod N, just keep adding N to −b until the number is between 0 and N
In your case, N = 5, b = −11. Add 5 to -11, you get -6, again you get -1, and again you get 4.
So, −11 mod 5 = 4.
Python's modulo operator (%) always return a number having the same sign as the denominator (divisor)
In -11%5 as 5 is a positive number, the output you got is positive
This question already has answers here:
How does the modulo (%) operator work on negative numbers in Python?
(12 answers)
Closed last month.
Been looking through other answers and I still don't understand the modulo for negative numbers in python
For example the answer by df
x == (x/y)*y + (x%y)
so it makes sense that (-2)%5 = -2 - (-2/5)*5 = 3
Doesn't this (-2 - (-2/5)*5) =0 or am I just crazy?
Modulus operation with negatives values - weird thing?
Same with this
negative numbers modulo in python
Where did he get -2 from?
Lastly if the sign is dependent on the dividend why don't negative dividends have the same output as their positive counterparts?
For instance the output of
print([8%5,-8%5,4%5,-4%5])
is
[3, 2, 4, 1]
In Python, modulo is calculated according to two rules:
(a // b) * b + (a % b) == a, and
a % b has the same sign as b.
Combine this with the fact that integer division rounds down (towards −∞), and the resulting behavior is explained.
If you do -8 // 5, you get -1.6 rounded down, which is -2. Multiply that by 5 and you get -10; 2 is the number that you'd have to add to that to get -8. Therefore, -8 % 5 is 2.
In Python, a // b is defined as floor(a/b), as opposed to most other languages where integer division is defined as trunc(a/b). There is a corresponding difference in the interpretation of a % b = a - (a // b) * b.
The reason for this is that Python's definition of the % operator (and divmod) is generally more useful than that of other languages. For example:
def time_of_day(seconds_since_epoch):
minutes, seconds = divmod(seconds_since_epoch, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
return '%02d:%02d:%02d' % (hours, minutes, seconds)
With this function, time_of_day(12345) returns '03:25:45', as you would expect.
But what time is it 12345 seconds before the epoch? With Python's definition of divmod, time_of_day(-12345) correctly returns '20:34:15'.
What if we redefine divmod to use the C definition of / and %?
def divmod(a, b):
q = int(a / b) # I'm using 3.x
r = a - b * q
return (q, r)
Now, time_of_day(-12345) returns '-3:-25:-45', which isn't a valid time of day. If the standard Python divmod function were implemented this way, you'd have to write special-case code to handle negative inputs. But with floor-style division, like my first example, it Just Works.
The rationale behind this is really the mathematical definition of least residue. Python respects this definition, whereas in most other programming language the modulus operator is really more like a 'reaminder after division' operator. To compute the least residue of -5 % 11, simply add 11 to -5 until you obtain a positive integer in the range [0,10], and the result is 6.
When you divide ints (-2/5)*5 does not evaluate to -2, as it would in the algebra you're used to. Try breaking it down into two steps, first evaluating the part in the parentheses.
(-2/5) * 5 = (-1) * 5
(-1) * 5 = -5
The reason for step 1 is that you're doing int division, which in python 2.x returns the equivalent of the float division result rounded down to the nearest integer.
In python 3 and higher, 2/5 will return a float, see PEP 238.
Check out this BetterExplained article and look # David's comment (No. 6) to get what the others are talking about.
Since we're working w/ integers, we do int division which, in Python, floors the answer as opposed to C. For more on this read Guido's article.
As for your question:
>>> 8 % 5 #B'coz (5*1) + *3* = 8
3
>>> -8 % 5 #B'coz (5*-2) + *2* = -8
2
Hope that helped. It confused me in the beginning too (it still does)! :)
Say -a % b needs to be computed. for ex.
r= 11 % 10
find the next number after 11 that is perfectly divisible by 10 i.e on dividing that next number after 11 gives the remainder 0.
In the above case its 20 which on dividing by 10 gives 0.
Hence, 20-11 = 9 is the number that needs to be added to 11.
The concept if 60 marbles needs to be equally divided among 8 people, actually what you get after dividing 60/8 is 7.5 since you can'nt halve the marbles, the next value after 60 that is perfectly divisible by 8 is 64. Hence 4 more marbles needs to be added to the lot so that everybody share the same joy of marbles.
This is how Python does it when negatives numbers are divided using modulus operator.
Exactly how does the % operator work in Python, particularly when negative numbers are involved?
For example, why does -5 % 4 evaluate to 3, rather than, say, -1?
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:
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
Essentially, it's so that a/b = q with remainder r preserves the relationships b*q + r = a and 0 <= r < b.
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
whereas other languages such as C, JAVA, JavaScript use truncation instead of floor.
>>> mod = n - int(n/base) * base
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.
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.
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
So in forward direction, your answer would be +1, but in backward direction-
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 -
Forward direction
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!!
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
Produces:
-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
Python % always outputs zero or positive*
Python // always rounds toward negative infinity
* ... as long as the right operand is positive. On the other hand 11 % -10 == -9
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.
You can use:
result = numpy.fmod(x,y)
it will keep the sign , see numpy fmod() documentation.
It's also worth to mention that also the division in python is different from C:
Consider
>>> x = -10
>>> y = 37
in C you expect the result
0
what is x/y in python?
>>> print x/y
-1
and % is modulo - not the remainder! While x%y in C yields
-10
python yields.
>>> print x%y
27
You can get both as in C
The division:
>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0
And the remainder (using the division from above):
>>> r = x - d*y
>>> print r
-10
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.
It's what modulo is used for. If you do a modulo through a series of numbers, it will give a cycle of values, say:
ans = num % 3
num
ans
3
0
2
2
1
1
0
0
-1
2
-2
1
-3
0
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).
#Deekshant has explained it well using visualisation. Another way to understand %(modulo) is ask a simple question.
What is nearest smaller number to dividend that can be divisible by divisor on X-axis ?
Let's have a look at few examples.
5 % 3
5 is Dividend, 3 is divisor. If you ask above question 3 is nearest smallest number that is divisible by divisor. ans would be 5 - 3 = 2. For positive Dividend, nearest smallest number would be always right side of dividend.
-5 % 3
Nearest smallest number that is divisible by 3 is -6 so ans would be -5 - (-6) = 1
-5 %4
Nearest smallest number that is divisible by 4 is -8 so ans would be -5 - (-8) = 3
Python answers every modulo expression with this method. Hope you can understand next how expression would be going to execute.
I attempted to write a general answer covering all input cases, because many people ask about various special cases (not just the one in OP, but also especially about negative values on the right-hand side) and it's really all the same question.
What does a % b actually give us in Python, explained in words?
Assuming that a and b are either float and/or int values, finite (not math.inf, math.nan etc.) and that b is not zero....
The result c is the unique number with the sign of b, such that a - c is divisible by b and abs(c) < abs(b). It will be an int when a and b are both int, and a float (even if it is exactly equal to an integer) when either a or b is an int.
For example:
>>> -9 % -5
-4
>>> 9 % 5
4
>>> -9 % 5
1
>>> 9 % -5
-1
The sign preservation also works for floating-point numbers; even when a is divisible by b, it is possible to get distinct 0.0 and -0.0 results (recalling that zero is signed in floating-point), and the sign will match b.
Proof of concept:
import math
def sign(x):
return math.copysign(1, x)
def test(a: [int, float], b: [int, float]):
c = a % b
if isinstance(a, int) and isinstance(b, int):
assert isinstance(c, int)
assert c * b >= 0 # same sign or c == 0
else:
assert isinstance(c, float)
assert sign(c) == sign(b)
assert abs(c) < abs(b)
assert math.isclose((a - c) / b, round((a - c) / b))
It's a little hard to phrase this in a way that covers all possible sign and type combinations and accounts for floating-point imprecision, but I'm pretty confident in the above. One specific gotcha for floats is that, because of that floating-point imprecision, the result for a % b might sometimes appear to give b rather than 0. In fact, it simply gives a value very close to b, because the result of the division wasn't quite exact:
>>> # On my version of Python
>>> 3.5 % 0.1
0.09999999999999981
>>> # On some other versions, it might appear as 0.1,
>>> # because of the internal rules for formatting floats for display
What if abs(a) < abs(b)?
A lot of people seem to think this is a special case, or for some reason have difficulty understanding what happens. But there is nothing special here.
For example: consider -1 % 3. How much, as a positive quantity (because 3 is positive), do we have to subtract from -1, in order to get a result divisible by 3? -1 is not divisible by 3; -1 - 1 is -2, which is also not divisible; but -1 - 2 is -3, which is divisible by 3 (dividing in exactly -1 times). By subtracting 2, we get back to divisibility; thus 2 is our predicted answer - and it checks out:
>>> -1 % 3
2
What about with b equal to zero?
It will raise ZeroDivisionError, regardless of whether b is integer zero, floating-point positive zero, or floating-point negative zero. In particular, it will not result in a NaN value.
What about special float values?
As one might expect, nan and signed infinity values for a produce a nan result, as long as b is not zero (which overrides everything else). nan values for b result in nan as well. NaN cannot be signed, so the sign of b is irrelevant in these cases.
Also as one might expect, inf % inf gives nan, regardless of the signs. If we are sharing out an infinite amount of as to an infinite amount of bs, there's no way to say "which infinity is bigger" or by how much.
The only slightly confusing cases are when b is a signed infinity value:
>>> 0 % inf
0.0
>>> 0 % -inf
-0.0
>>> 1 % inf
1.0
>>> 1 % -inf
-inf
As always, the result takes the sign of b. 0 is divisible by anything (except NaN), including infinity. But nothing else divides evenly into infinity. If a has the same sign as b, the result is simply a (as a floating-point value); if the signs differ, it will be b. Why? Well, consider -1 % inf. There isn't a finite value we can subtract from -1, in order to get to 0 (the unique value that we can divide into infinity). So we have to keep going, to infinity. The same logic applies to 1 % -inf, with all the signs reversed.
What about other types?
It's up to the type. For example, the Decimal type overloads the operator so that the result takes the sign of the numerator, even though it functionally represents the same kind of value that a float does. And, of course, strings use it for something completely different.
Why not always give a positive result, or take the sign of a?
The behaviour is motivated by integer division. While % happens to work with floating-point numbers, it's specifically designed to handle integer inputs, and the results for floats fall in line to be consistent with that.
After making the choice for a // b to give a floored division result, the % behaviour preserves a useful invariant:
>>> def check_consistency(a, b):
... assert (a // b) * b + (a % b) == a
...
>>> for a in range(-10, 11):
... for b in range(-10, 11):
... if b != 0:
... check_consistency(a, b) # no assertion is raised
...
In other words: adding the modulus value back, corrects the error created by doing an integer division.
(This, of course, lets us go back to the first section, and say that a % b simply computes a - ((a // b) * b). But that just kicks the can down the road; we still need to explain what // is doing for signed values, especially for floats.)
One practical application for this is when converting pixel coordinates to tile coordinates. // tells us which tile contains the pixel coordinate, and then % tells us the offset within that tile. Say we have 16x16 tiles: then the tile with x-coordinate 0 contains pixels with x-coordinates 0..15 inclusive, tile 1 corresponds to pixel coordinate values 16..31, and so on. If the pixel coordinate is, say, 100, we can easily calculate that it is in tile 100 // 16 == 6, and offset 100 % 16 == 4 pixels from the left edge of that tile.
We don't have to change anything in order to handle tiles on the other side of the origin. The tile at coordinate -1 needs to account for the next 16 pixel coordinates to the left of 0 - i.e., -16..-1 inclusive. And indeed, we find that e.g. -13 // 16 == -1 (so the coordinate is in that tile), and -13 % 16 == 3 (that's how far it is from the left edge of the tile).
By setting the tile width to be positive, we defined that the within-tile coordinates progress left-to-right. Therefore, knowing that a point is within a specific tile, we always want a positive result for that offset calculation. Python's % operator gives us that, on both sides of the y-axis.
What if I want it to work another way?
math.fmod will take the sign of the numerator. It will also return a floating-point result, even for two integer inputs, and raises an exception for signed-infinity a values with non-nan b values:
>>> math.fmod(-13, 16)
-13.0
>>> math.fmod(13, -16)
13.0
>>> math.fmod(1, -inf) # not -inf
1.0
>>> math.fmod(inf, 1.0) # not nan
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
It otherwise handles special cases the same way - a zero value for b raises an exception; otherwise any nan present causes a nan result.
If this also doesn't suit your needs, then carefully define the exact desired behaviour for every possible corner case, figure out where they differ from the built-in options, and make a wrapper function.