Python % Operator
00:00
In the previous lesson, I introduced you to modular arithmetic. In this lesson, I’ll show you how to use the %
operator to accomplish the same thing in Python.
00:12
The %
operator is the modulus operator. Just like in the previous lesson, 13 mod 12 is 1. 13 divided by 12 has a remainder of 1, hence the result.
00:25 Here’s another one for 15 mod 4. And a bigger value, 240 mod 13. Because the mod operator involves division, you have the same problem if you do a mod by 0, as if you did a divide by 0.
00:40
You’ll get a ZeroDivisionError
raised in this case. In the previous lesson, I showed you that negatives were possible. 8 mod -3 is -1. You have to be a little careful with negative numbers.
00:54 There’s two different ways of calculating mod, and you can get two different results depending on which mechanism you’re using. I’ll show you more about that a little later.
01:03
The %
operator also supports floating-point. Floating-point values going in result in floating-point values coming out. If you haven’t played much with floating-point before, you might be a little surprised at the following little piece of math.
01:18
.1 + .1 + .1
isn’t 0.3
. This has to do with how your computer stores these kinds of numbers and the floating-point standard. Mod on floating-point has the same kind of precision problem as this addition example I just showed you.
01:35 Little inaccuracies sneak in.
01:39 You should always be cautious with floating-point, and this is why you should never use floating-point values to store money. These kinds of errors accumulate over time.
01:49
Python has a class called Decimal
, capital D
, inside of the decimal
module. It has arbitrary precision and doesn’t have this problem.
01:58
I’ll show you more about these later. There are two ways of doing modular arithmetic in Python: the %
operator and inside of the math
library, fmod()
.
02:14
Generally, it’s recommended to use the %
operator when dealing with integers and the fmod()
function when dealing with floating-point.
02:22
Remember how I mentioned earlier that negatives are a problem? It turns out that %
for integers and floats and fmod()
calculate negative modulus differently, and so you’ll get inconsistent results.
02:36
Here’s a large exponent, and here’s the same using the %
operator. You have a significantly different value showing up there. This problem with negatives that I’ve shown you isn’t just within Python.
02:49
It’s also between different languages. Not all programming languages calculate the negative modulus the same way. 8 % -3
in JavaScript is 2
. In Python, the same calculation is -1
.
03:04
There are two common ways of calculating mod. Here’s how Python’s %
operator does it. The remainder is calculated as a minus n times the floor of a divided by n.
03:18 Here’s an example. 13 mod 12 is 13 minus 12 times the floor of 13 over 12. Or 13 minus 12 times the floor of 1.083. The floor of 1.083 is 1, so you end up with 13 minus 12 times 1, which is a remainder of 1. Now let’s do that again with a negative number. 8 mod -3 gives you 8 minus -3 times the floor of 8 divided by -3.
03:52
8 divided by -3 gives you minus 2.6 repeated, the floor of which is -3, giving you 9 on the right-hand side and remainder of -1. JavaScript’s %
operator calculates things slightly differently. For the same operation, instead of using floor()
, it uses trunc()
. For whole numbers, this isn’t a problem.
04:18
The end result is the same calculation as you saw before. Unfortunately, for negative numbers it is a problem. When you get to the trunc()
step of 8 divided by -3, the truncation of -2.6 repeated is -2.
04:36 This changes the value on the right-hand side and thus changes the result.
04:42
In Python, the %
operator uses floor()
, but the math.fmod()
uses trunc()
. This is what causes the difference that I showed you earlier between negative values for %
and fmod()
. You need to be aware of this if you’re doing modulus math on negative values.
05:01
8 % -3
is -1
, whereas the fmod()
on the same value is 2
. This is the same as the JavaScript versus Python example I just showed you.
05:13
In addition to the mod methods I’ve shown you so far, Python also has a function called divmod()
.
05:20
divmod()
returns two values—both the result of the division and the remainder. 12 goes into 13 once, so you get the first part of the tuple, and has a remainder of 1, giving you the second part of the tuple.
05:34
5 goes into 37 7 times and has a remainder of 2 when it’s done. The divmod()
function is the equivalent of running two different Python operations at the same time.
05:47
First off, strict integer division, expressed by the double slashes (//
). 37 // 5
is 7
. And secondly, %
operator. 37 % 5
is 2
, divmod(37, 5)
giving you the same as these two results but in one function call. Note that divmod()
uses the same mechanism as %
. So if you’re dealing with negative values, you’ll get the kind of calculation that the %
operator does—not the kind of calculation that fmod()
uses. In Python, the %
operator is considered to have the same operator precedence as division and multiplication.
06:31 4 times 10 is 40, 12 goes into 40 3 times with a remainder of 4, 4 minus 9 gives you -5. Adding some brackets to the same statement changes the value. Now you’re doing 40 mod 3 instead.
06:49
That’s the basic usage of %
and fmod()
in Python. In the next lesson, I’ll show you some common uses of these operators inside of code.
Become a Member to join the conversation.