Python provides two distinct division operators: / (true division) and // (floor division). They look similar but behave very differently, especially in the type of value they return and how they handle negative numbers. Understanding the distinction between them is essential for avoiding subtle bugs in calculations, indexing, pagination, and any logic that depends on integer results.
This guide explains how each operator works, highlights the critical differences with negative numbers, and demonstrates practical use cases where choosing the right operator matters.
True Division with /
The single slash operator performs standard mathematical division. It always returns a float, even when both operands are integers and the result is a whole number:
print(10 / 2)
print(7 / 2)
print(1 / 3)Output:
5.0
3.5
0.3333333333333333This behavior is consistent regardless of the types you pass in:
print(10.0 / 2)
print(10 / 2.0)
print(10 / 2)Output:
5.0
5.0
5.0The result is always float, no matter what combination of int and float operands you use.
Floor Division with //
The double slash operator divides and then rounds the result down to the nearest integer (toward negative infinity). This is called the "floor" of the result:
print(10 // 2)
print(7 // 2)
print(1 // 3)Output:
5
3
0Unlike true division, the return type depends on the operands. If both operands are integers, the result is an integer. If either operand is a float, the result is a float (but still mathematically floored):
print(10 // 3)
print(10.0 // 3)
print(10 // 3.0)Output:
3
3.0
3.0The Negative Number Trap
This is where most confusion and bugs arise. Floor division rounds toward negative infinity, not toward zero. With positive numbers, these two directions are the same. With negative numbers, they are not:
print(7 // 2)
print(-7 // 2)
print(7 // -2)
print(-7 // -2)Output:
3
-4
-4
3The true division result of -7 / 2 is -3.5. The floor of -3.5 is -4 (the next integer toward negative infinity), not -3. This is mathematically correct floor behavior, but it surprises many developers who expect truncation toward zero, which is the default behavior in languages like C, Java, and JavaScript.
When you need truncation toward zero
If your logic requires C-style integer division that truncates the decimal part (rounds toward zero), you have two options:
print(-7 // 2)
print(int(-7 / 2))
import math
print(math.trunc(-7 / 2))Output:
-4
-3
-3How Floor Division Pairs with Modulo
Floor division and the modulo operator (%) are designed to work together. They satisfy this mathematical identity for any integers a and b (where b is not zero):
a == (a // b) * b + (a % b)This means you can always reconstruct the original value from the quotient and remainder:
a, b = 17, 5
quotient = a // b
remainder = a % b
print(f"quotient: {quotient}")
print(f"remainder: {remainder}")
print(f"reconstruction: {quotient * b + remainder}")Output:
quotient: 3
remainder: 2
reconstruction: 17The built-in divmod() function returns both values at once, which is convenient and slightly more efficient when you need both:
print(divmod(17, 5))Output:
(3, 2)This identity holds consistently with negative numbers as well:
a, b = -17, 5
quotient = a // b
remainder = a % b
print(f"quotient: {quotient}")
print(f"remainder: {remainder}")
print(f"reconstruction: {quotient * b + remainder}")Output:
-quotient: -4
remainder: 3
reconstruction: -17Practical Use Cases for Floor Division
Pagination
When dividing items across pages, you need integer page counts. A common pattern is ceiling division to ensure the last partial page is included:
items = 47
per_page = 10
total_pages = items / per_page
print(total_pages)
total_pages = (items + per_page - 1) // per_page
print(total_pages)
total_pages = -(-items // per_page)
print(total_pages)Output:
4.7
5
5Time Conversions
Converting a flat count of seconds into hours, minutes, and seconds is a natural fit for // and %:
total_seconds = 3672
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
print(f"{hours}h {minutes}m {seconds}s")Output:
1h 1m 12sArray Midpoint in Binary Search
List indices must be integers. Floor division ensures you always get a valid index:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2 # Integer index required
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
numbers = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
print(binary_search(numbers, 23))Output:
5Digit Extraction
Floor division and modulo together can extract individual digits from an integer:
number = 4567
ones = number % 10
tens = (number // 10) % 10
hundreds = (number // 100) % 10
thousands = (number // 1000) % 10
print(f"Digits: {thousands}, {hundreds}, {tens}, {ones}")Output:
Digits: 4, 5, 6, 7Common Mistake: Using / Where // Is Needed
A frequent source of bugs is using true division when an integer result is required, then passing the float to something that expects an integer:
data = [10, 20, 30, 40, 50]
mid = len(data) / 2
print(mid)
print(data[mid])Output:
2.5
TypeError: list indices must be integers or slices, not floatThe fix is to use floor division:
data = [10, 20, 30, 40, 50]
mid = len(data) // 2
print(mid)
print(data[mid])Output:
2
30Operator Summary
| Operator | Name | Result Type | Rounding Direction |
|---|---|---|---|
/ |
True Division | Always float |
No rounding |
// |
Floor Division | int if both operands are int, otherwise float |
Toward negative infinity |
% |
Modulo | int if both operands are int, otherwise float |
Pairs with // |
Quick Reference
print(10 / 4) # 2.5
print(10 / 2) # 5.0
print(10 // 4) # 2
print(-10 // 4) # -3 (not -2!)
print(-(-10 // 4)) # 3
print(divmod(10, 4)) # (2, 2)
print(int(-10 / 4)) # -2Output:
2.5
5.0
2
-3
3
(2, 2)
-2Summary
Python's two division operators serve different purposes:
- Use
/(true division) for standard mathematical division where you need the full decimal result. It always returns afloat. - Use
//(floor division) when you need an integer result, such as for list indexing, pagination, counting, or time conversions. It rounds toward negative infinity. - Be especially careful with negative numbers:
//rounds toward negative infinity, not toward zero. If you need truncation toward zero, useint()with true division ormath.trunc(). - Use
divmod()when you need both the quotient and the remainder in a single operation. - Floor division and modulo satisfy the identity
a == (a // b) * b + (a % b), which makes them reliable building blocks for arithmetic decomposition.