Master math.floor() and downward rounding techniques
Rounding down means always moving toward the smaller value (toward negative infinity). In Python, the primary method for rounding down is math.floor(), but there are several techniques depending on your specific needs.
This guide covers all methods for rounding down in Python, including math.floor(), int() for positive numbers, custom functions for decimal places, and important differences with negative numbers.
math.floor(x)The math.floor() function returns the largest integer less than or equal to x. It always rounds DOWN toward negative infinity.
import math # Positive numbers - round down to lower integer print(math.floor(3.9)) # Output: 3 print(math.floor(3.1)) # Output: 3 print(math.floor(3.0)) # Output: 3 (already integer) print(math.floor(7.999)) # Output: 7 # Negative numbers - toward negative infinity print(math.floor(-3.1)) # Output: -4 (down means more negative) print(math.floor(-3.9)) # Output: -4 print(math.floor(-2.01)) # Output: -3 # Edge cases print(math.floor(0)) # Output: 0 print(math.floor(0.1)) # Output: 0 print(math.floor(-0.1)) # Output: -1
math.floor() always rounds toward negative infinity. For negative numbers, this means rounding to a MORE NEGATIVE value (which is mathematically "down"):
# -3.1 is between -4 and -3 # Floor goes to -4 (toward -∞) print(math.floor(-3.1)) # -4 # -3.9 is between -4 and -3 # Floor goes to -4 (toward -∞) print(math.floor(-3.9)) # -4
import mathresult = math.floor(5.7)print(result) # 5int(x)The built-in int() function truncates toward zero. For positive numbers, this is the same as rounding down. For negative numbers, it's different!
# Positive numbers - int() rounds down (same as floor) print(int(3.9)) # Output: 3 print(int(3.1)) # Output: 3 print(int(7.999)) # Output: 7 # Negative numbers - int() rounds UP toward zero (different!) print(int(-3.9)) # Output: -3 (not -4!) print(int(-3.1)) # Output: -3 (not -4!) # Compare to floor() print(math.floor(-3.9)) # Output: -4 print(int(-3.9)) # Output: -3
If you need true "round down" behavior for all numbers (including negatives), always use math.floor(). The int() function truncates toward zero, which rounds UP for negative numbers.
# WRONG for rounding down negative numbers int(-3.7) # -3 (rounds UP toward zero) # CORRECT for rounding down all numbers math.floor(-3.7) # -4 (rounds DOWN toward -∞)
Understanding the differences between these three functions is crucial for correct rounding behavior:
| Function | 3.7 | -3.7 | Direction | Use Case |
|---|---|---|---|---|
| math.floor() | 3 | -4 | Toward -∞ | True round down |
| int() | 3 | -3 | Toward 0 | Positive numbers only |
| math.trunc() | 3 | -3 | Toward 0 | Remove decimal part |
import math
number = 3.7
print(f"math.floor({number}) = {math.floor(number)}") # 3
print(f"int({number}) = {int(number)}") # 3
print(f"math.trunc({number}) = {math.trunc(number)}") # 3
number = -3.7
print(f"math.floor({number}) = {math.floor(number)}") # -4 ← Only this rounds DOWN
print(f"int({number}) = {int(number)}") # -3
print(f"math.trunc({number}) = {math.trunc(number)}") # -3math.floor() only rounds to integers. To round down to a specific number of decimal places, you need a custom function:
import math
def floor_to_decimals(number, decimals=0):
"""
Round DOWN to specified decimal places.
Args:
number: The number to round
decimals: Number of decimal places (default: 0)
Returns:
Number rounded down to specified decimal places
"""
multiplier = 10 ** decimals
return math.floor(number * multiplier) / multiplier
# Examples
print(floor_to_decimals(3.999, 2)) # Output: 3.99
print(floor_to_decimals(3.999, 1)) # Output: 3.9
print(floor_to_decimals(3.999, 0)) # Output: 3.0
print(floor_to_decimals(12.9876, 2)) # Output: 12.98
print(floor_to_decimals(12.9876, 3)) # Output: 12.987
# Negative numbers
print(floor_to_decimals(-3.999, 2)) # Output: -4.00
print(floor_to_decimals(-12.9876, 2)) # Output: -12.99Move the decimal point right
3.999 × 100 = 399.9Round down to integer
floor(399.9) = 399Move the decimal point back
399 / 100 = 3.99import math
# Calculate complete groups
total_items = 47
items_per_box = 10
complete_boxes = math.floor(total_items / items_per_box)
print(f"Complete boxes: {complete_boxes}") # Output: 4
remaining = total_items % items_per_box
print(f"Items remaining: {remaining}") # Output: 7import math
# Calculate array index from floating point position
position = 7.8
index = math.floor(position)
arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
print(f"Element at position {position}: {arr[index]}")
# Output: Element at position 7.8: h
# Another example: pixel coordinates
pixel_x = 123.7
pixel_y = 456.2
x_index = math.floor(pixel_x)
y_index = math.floor(pixel_y)
print(f"Pixel at ({x_index}, {y_index})") # (123, 456)import math
def get_page_number(item_index, items_per_page):
"""Calculate which page an item is on (0-indexed)"""
return math.floor(item_index / items_per_page)
# Examples
print(f"Item 0 is on page: {get_page_number(0, 10)}") # 0
print(f"Item 9 is on page: {get_page_number(9, 10)}") # 0
print(f"Item 10 is on page: {get_page_number(10, 10)}") # 1
print(f"Item 25 is on page: {get_page_number(25, 10)}") # 2import math
def floor_to_decimals(number, decimals):
multiplier = 10 ** decimals
return math.floor(number * multiplier) / multiplier
# Round down profit estimates (conservative)
projected_profit = 1234.89
conservative_estimate = floor_to_decimals(projected_profit, 0)
print(f"Conservative estimate: {conservative_estimate}")
# Output: 1234.0
# Round down discounts (customer-friendly)
original_price = 99.99
discount_rate = 0.15
max_discount = floor_to_decimals(original_price * discount_rate, 2)
print(f"Maximum discount: {max_discount}")
# Output: 14.99import math
# Calculate complete hours worked
minutes_worked = 475
complete_hours = math.floor(minutes_worked / 60)
remaining_minutes = minutes_worked % 60
print(f"Worked: {complete_hours}h {remaining_minutes}m")
# Output: Worked: 7h 55m
# Calculate number of complete days
hours = 73.5
complete_days = math.floor(hours / 24)
print(f"Complete days: {complete_days}")
# Output: Complete days: 3# WRONG - int() rounds toward zero, not down
def round_down(x):
return int(x) # Fails for negative numbers!
print(round_down(-3.7)) # -3 (should be -4)✓ Correct:
import math
def round_down(x):
return math.floor(x) # Works for all numbers
print(round_down(-3.7)) # -4 (correct!)# WRONG - NameError result = floor(3.7) # NameError: name 'floor' is not defined
✓ Correct:
import math result = math.floor(3.7) # Works!
# Similar but not identical for negative numbers with decimals print(3.7 // 1) # 3.0 (works) print(-3.7 // 1) # -4.0 (works) # But // returns float if either operand is float print(type(3.7 // 1)) # <class 'float'> print(type(math.floor(3.7))) # <class 'int'>
math.floor() works correctly for both positive and negative numbers. Avoid int() unless you're certain you only have positive numbers.
Wrap the multiply-floor-divide pattern in a reusable function for cleaner code.
Always test your rounding logic with negative numbers to ensure it behaves as expected.
Make it clear in comments and documentation how your code handles rounding, especially edge cases.
Complete guide to all Python rounding methods
Complete overview of Python's rounding ecosystem
Master math.ceil() and upward rounding
Specific guide for 2 decimal place rounding
JavaScript rounding to 2 decimal places
Complete Java rounding guide