Round up/down decimals in Python (math.floor, math.ceil)

Modified: | Tags: Python, Numeric

In Python, math.floor() and math.ceil() are used to round down and up floating point numbers (float).

Note that math.floor() rounds toward negative infinity and math.ceil() rounds toward positive infinity.

Here's a summary of the results. You can use int() to round toward zero (i.e., truncate or round away from infinity), but rounding toward infinity requires a custom function discussed later.

print(math.floor(10.123))
# 10

print(math.floor(-10.123))
# -11

print(math.ceil(10.123))
# 11

print(math.ceil(-10.123))
# -10

print(int(10.123))
# 10

print(int(-10.123))
# -10

You can use round() to round half to even.

To round up and down the elements in a NumPy array (ndarray), see the following article.

Round down (= take the floor): math.floor()

Use math.floor() to round down. It returns an integer (int).

import math

print(math.floor(10.123))
# 10

print(math.floor(10.987))
# 10

print(type(math.floor(10.123)))
# <class 'int'>

While this function leaves integers (int) unchanged, it raises an error for non-numeric types like strings (str), which lack a __floor__() method.

print(math.floor(10))
# 10

# print(math.floor('10'))
# TypeError: must be real number, not str

print(hasattr(10, '__floor__'))
# True

print(hasattr('10', '__floor__'))
# False

math.floor(x) returns the floor of x, the largest integer less than or equal to x. That is, it rounds to negative infinity.

For negative values, the results are as follows.

print(math.floor(-10.123))
# -11

print(math.floor(-10.987))
# -11

To truncate absolute values without changing the sign, i.e., to round toward zero, use int() described below.

Round up (= take the ceiling): math.ceil()

Use math.ceil() to round up. It returns an integer (int).

import math

print(math.ceil(10.123))
# 11

print(math.ceil(10.987))
# 11

print(type(math.ceil(10.123)))
# <class 'int'>
source: math_ceil.py

While this function leaves integers (int) unchanged, it raises an error for non-numeric types like strings (str), which lack a __ceil__() method.

print(math.ceil(10))
# 10

# print(math.ceil('10'))
# TypeError: must be real number, not str

print(hasattr(10, '__ceil__'))
# True

print(hasattr('10', '__ceil__'))
# False
source: math_ceil.py

math.ceil(x) returns the ceiling of x, the smallest integer greater than or equal to x. That is, it rounds to positive infinity.

For negative values, the results are as follows.

print(math.ceil(-10.123))
# -10

print(math.ceil(-10.987))
# -10
source: math_ceil.py

To round up the absolute value without changing the sign, i.e., to round toward infinity, you need to define a custom function described below.

Difference between math.floor() and int()

You can also use int() to round down.

int() returns the same result as math.floor() for positive values.

print(int(10.123))
# 10

print(int(10.987))
# 10

print(int(10))
# 10

print(type(int(10.123)))
# <class 'int'>

The result for negative values is different from math.floor().

While math.floor() rounds toward negative infinity, int() instead rounds toward zero.

print(int(-10.123))
# -10

print(int(-10.987))
# -10

Additionally, int() can convert strings (str) to integers (int). Although it cannot directly convert floating-point number strings, it can handle binary or hexadecimal strings using the second argument, base.

print(int('10'))
# 10

# print(int('10.123'))
# ValueError: invalid literal for int() with base 10: '10.123'

print(int('FF', 16))
# 255

Round toward infinity

Considering negative values, there are four ways to round up and down.

As described above, you can use the following functions for rounding:

  • Round toward negative infinity: math.floor()
  • Round toward positive infinity: math.ceil()
  • Round toward zero: int()
  • Round toward infinity
print(math.floor(10.123))
# 10

print(math.floor(-10.123))
# -11

print(math.ceil(10.123))
# 11

print(math.ceil(-10.123))
# -10

print(int(10.123))
# 10

print(int(-10.123))
# -10

For example, you can define a custom function that rounds toward infinity as follows.

def round_towards_infinity(x):
    return int(math.copysign(math.ceil(abs(x)), x))

print(round_towards_infinity(10.123))
# 11

print(round_towards_infinity(-10.123))
# -11

This custom function uses abs() to get the absolute value, math.ceil() for rounding up, and math.copysign() to retain the original sign. The resulting float from math.copysign() is then converted to an integer using int().

Related Categories

Related Articles