Pythons three division operators, tips and gotchas
Python’s Division Operators #
Python has three division operators: /
, //
, and %
. Each serves a different purpose:
/
performs true division, returning a float.//
performs floor division, returning the largest integer less than or equal to the result.%
gives the modulus, returning the remainder of the division.
True Division (/) #
The true division operator /
divides two numbers and returns a float. If both operands are integers, the result will still be a float.
So it is the typical maths division that learned at school.
# True division
result = 9 / 3
print(result) # Output: 3.0
print(type(result)) # Output: <class 'float'>
Unit Conversions with Chaining #
Using the true division operator to convert units is a common and probably obvious use case.
# Convert seconds to hours
seconds = 3600
hours = seconds / 3600
print(hours) # Output: 1.0
However, Python allows you to chain division operations, making your code easier to read.
# convert bytes to megabytes
bytes = 1048576
megabytes = bytes / 1024 / 1024
print(megabytes) # Output: 1.0
Watch out for Repeating Decimals #
Note that mathematical division can result in repeating decimals.
In maths, the result of 7 / 3
is 2.3333333...
, with the number 3 repeating indefinitely.
However, Python can only store a finite number of decimal places, so it approximates the result to a certain precision.
Notice the result contains a 5 at the end, due to the precision loss in the floating-point representation.
# True division with repeating decimal`
result = 7 / 3
print(result) # Output: 2.3333333333333335
Use round() for Precision Control #
When you need to control the precision of a floating-point number, you can use the built-in round()
function. This function allows you to specify the number of decimal places you want to keep.
# Controlling precision with round()
result = 7 / 3
rounded_result = round(result, 2)
print(rounded_result) # Output: 2.33
Use math.isclose() for Comparison #
When comparing floating-point numbers, it’s often better to use the math.isclose()
function to avoid issues with precision errors. This function was introduced in Python 3.5 and checks if two floating-point numbers are close to each other within a specified tolerance.
import math
# Comparing floating-point numbers
result1 = 7 / 3
result2 = 2.3333333333333335
print(math.isclose(result1, result2)) # Output: True
Floor Division (//) #
The floor division operator //
divides two numbers and returns the largest value that is less than or equal to the result.
Note that the result is never rounded up. It is basically stripping out the decimal numbers.
For example, 7 divided by 3 is 2.333…, so the floor division result is 2. 9 divided by 2 is 4.5, so the floor division result is 4. 26 divided by 10 is 2.6, so the floor division result is 2.
>>> 9//2
4
>>> 7//3
2
>>> 26//10
2
>>> 1//2
0
Floor Division with Negative Numbers #
Since floor division always rounds down, be careful with negative numbers.
See the following example, where you might have expected the result to be -3.
>>> -7//2
-4
Unit Conversions #
As with true division, floor division can also be used for unit conversions, if you just want the whole number part of the result.
# Convert seconds to hours using floor division
seconds = 120
minutes = seconds // 60
print(minutes) # Output: 2
# outputs 1, even though 119 is almost 2 minutes
seconds = 119
minutes = seconds // 60
print(minutes) # Output: 1
always rounding down has some use cases
The rounding behavior may seem counterintuitive at first, but if you are, for example, displaying the number of minutes as part of a clock, rounding down is what you need.
Pagination #
Floor division is also useful for pagination, where you want calculate how many pages are required to display a certain number of items, or what page an item is on.
# Pagination example
total_items = 53
items_per_page = 10
required_pages = (total_items - 1) // items_per_page + 1
print(required_pages) # Output: 6
Note that you cannot use
required_pages = total_items // items_per_page + 1
Because when total_items is a multiple of items_per_page, the result would be one too high. e.g. if total_items is 20, then the result would be 3, but you only need 2 pages.
Mixing Types #
When using floor division, the result is not always an integer. If one of the operands is a float, the result will be a float as well.
# Mixing types in floor division
result = 7 // 2.0
print(result) # Output: 3.0
print(type(result)) # Output: <class 'float'>
result = 7.0 // 2
print(result) # Output: 3.0
print(type(result)) # Output: <class 'float'>
result = 7 // 2
print(result) # Output: 3
print(type(result)) # Output: <class 'int'>
Modulus (%) #
The modulus operator %
returns the remainder of the division of two numbers.
So 7 divided by 3 is 2
3 times 2 is 6
take 6 away from 7, and you are left with 1, the remainder.
# Modulus operator examples
>>> 7 % 3
1
>>> 1 % 2
1
>>> 9 % 9
0
Odd and Even Numbers #
One of the most popular uses of the modulus operator is to determine if a number is odd or even.
# Check if a number is even or odd
number = 7
if number % 2 == 0:
print(f"{number} is even")
else:
print(f"{number} is odd")
# Output: 7 is odd
Circular Arrays #
A circular array is an array that wraps around when you reach the end. e.g. if you have an array of size 5, the index 5 wraps around to index 0.
For example, if you have an array that represents the days of the week, and you want to find the day that is 3 days after Friday, you can use the modulus operator to wrap around.
# Circular array example
days_of_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
current_day_index = 4 # Friday
days_to_add = 3
new_day_index = (current_day_index + days_to_add) % len(days_of_week)
print(days_of_week[new_day_index]) # Output: Monday
Unit Conversions #
As with the other division operators, the modulus operator can also be useful for unit conversions. Coupled with floor division, it can help you obtain the separate time units such as minutes and seconds when given only seconds..
# Convert seconds to minutes and seconds
total_seconds = 125
minutes = total_seconds // 60
seconds = total_seconds % 60
print(f"{total_seconds} seconds is {minutes} minutes and {seconds} seconds.")
# Output: 125 seconds is 2 minutes and 5 seconds.
Negative Numbers #
As with the floor division operator, be careful with negative numbers when using the modulus operator. The result will always have the same sign as the divisor.
# Modulus with negative numbers
result = -7 % 3
print(result) # Output: 2
result = 7 % -3
print(result) # Output: -2
You may be wondering why the result is 2 and -2, rather than -1 and 1, which would be the result if you just subtracted the divisor from the dividend.
Other languages behave differently
This is especially odd if you are used to the modulus operator in other programming languages, e.g. in C or Java, the result is always in the range of 0 to the divisor. i.e. in Java -7 % 3
would yield -1
, and 7 % -3
would yield 1
.
The reason is because Python follows this formula for the modulus operator :
a == ( a // b ) * b + ( a % b )
If a and b are both positive, respectively 7 and 3, then
7 == ( 7 // 3 ) * 3 + ( 7 % 3 )
7 == 2 * 3 + 1
7 == 6 + 1
7 == 7
If a is negative and b is positive, respectively -7 and 3, then
-7 == ( -7 // 3 ) * 3 + ( -7 % 3 )
-7 == -3 * 3 + 2
-7 == -9 + 2
-7 == -7
If a is positive and b is negative, respectively 7 and -3, then
7 == ( 7 // -3 ) * -3 + ( 7 % -3 )
7 == -3 * -3 + -2
7 == 9 - 2
7 == 7