Python Math floor(), ceil(), trunc(), and modf()

This article is the first of several articles discussing functions from the math module from the Python Standard Library. The articles are organized thematically; functions that are closely related to each other are discussed in the same article.

In this article, we discuss four functions:

  • math.floor,
  • math.ceil,
  • math.trunc, and
  • math.modf.

They are all related to the simple fact that a decimal x can be decomposed into an integer part n and a fractional part r (so that 0<r<1). For instance, if x=9.1, then the integer part is n=9 and the fractional part is r=0.1. On the other hand, if x=βˆ’9.1, then the integer and fractional parts are respectively n=βˆ’9,Β r=βˆ’0.1.

❗ Exercise: What are the integer and fractional parts of pi?

Since the main purpose of this blog is to discuss tools and techniques that are useful for Python freelancing, we will talk about how to utilize these functions in Python.

The Floor Function

math.floor(float)

Let’s first recall what the floor function βŒŠβ‹…βŒ‹ does in mathematical terms. For a real number x, its floor function ⌊xβŒ‹ is just x “rounded down”, i.e. the largest integer not exceeding x. In particular, if x is an integer, then its floor is just itself.

For instance, if x=9.1, then the floor of x is just 9. On the other hand, if x=βˆ’9.1, then the largest integer not exceeding x is βˆ’10 (rather than βˆ’9), so ⌊xβŒ‹=βˆ’10.

If we rephrase this in terms of the integer part n of x, we get

❗ Exercise. What is ⌊xβŒ‹ when x is:

  • a.) 2,
  • b.) 4.12,
  • c.) -12.12,
  • d.) 0.

To implement the floor function in Python, use the math.floor function. It takes in a float value x and returns an int class object.

import math
lst = [1.5, 3, -6.2, math.pi, 0, 2.71828, 29.0 , -91.312, math.sqrt(2)]
for x in lst: 
    print("math.floor(" + str(x) + "): " + str(math.floor(x)))

Output:

math.floor(1.5): 1
math.floor(3): 3
math.floor(-6.2): -7
math.floor(3.141592653589793): 3
math.floor(0): 0
math.floor(2.71828): 2
math.floor(29.0): 29
math.floor(-91.312): -92
math.floor(1.4142135623730951): 1

The graph of a floor function looks like a staircase. (Matplotlib does not do a precise job of graphing the function near the integer points. What should the graph look like near those points?)

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5,5,10000)

y = np.floor(x)
plt.title("Graph of Floor Function using Matplotlib.")
plt.plot(x,y)
plt.show()

Two other basic functions in Python are int() and // (integer division). For positive integers, int() returns the same value as math.floor(). Integer division by 1 returns the same value as math.floor() converted to floating point.

print(int(7.12)) 
print(math.floor(7.12)) 
print(7.12//1) 

print(int(3.1415)) 
print(math.floor(3.1415)) 
print(3.1415//1) 

Output:

7
7
7.0
3
3
3.0

However, they return different results when we look at negative non-integers:

print(int(-7.12)) 
print(math.floor(-7.12)) 
print(-7.12//1) 

print(int(-3.1415)) 
print(math.floor(-3.1415)) 
print(-3.1415//1) 

Output:

-7
-8
-8.0
-3
-4
-4.0
ο»Ώ

The Ceil Function

math.ceil(float)

Next we will look at the ceil function βŒˆβ‹…βŒ‰. Just as the floor function is the real number x rounded down, ⌈xβŒ‰ is just x “rounded up”, i.e. the smallest integer greater than x.

For instance, if x=9.1, then the ceil of x is just 10. On the other hand, if x=βˆ’9.1, then the smallest integer greater than x is βˆ’9, so ⌈xβŒ‰=βˆ’9. If x is an integer, then its ceil is just itself.

If we phrase this in terms of the integer and fractional part from before, we get

You can see from the above discussion that if x is not an integer, then ⌈xβŒ‰=⌊xβŒ‹+1

🧩 Exercise. What is ⌈xβŒ‰ when x is

  • a.) 2,
  • b.) 4.12,
  • c.) -12.12,
  • d.) 0.

The math.ceil() function is very similar to the math.floor() function. It takes in a float value and returns an int value:

for x in lst: 
    print("math.ceil(" + str(x) + "): " + str(math.ceil(x)))

Output:

math.ceil(1.5): 2
math.ceil(3): 3
math.ceil(-6.2): -6
math.ceil(3.141592653589793): 4
math.ceil(0): 0
math.ceil(2.71828): 3
math.ceil(29.0): 29
math.ceil(-91.312): -91
math.ceil(1.4142135623730951): 2

The graph of the math.ceil() is also a staircase. It is the same graph as math.floor() but shifted 1 unit upward. (By precalculus, this is a consequence of math.ceil(x) = 1 + math.floor(x) which we observed above.)

x = np.linspace(-5,5,10000)

y = np.ceil(x)
plt.title("Graph of Ceil Function using Matplotlib.")
plt.plot(x,y)
plt.show()

The Trunc Function

math.trunc(float)

The truncation function takes a real number x and returns its integer part n. (Unlike βŒˆβ‹…βŒ‰ and βŒŠβ‹…βŒ‹, there isn’t a standard way of writing the truncation function.)

The math.trunc() method does the same thing as int() applied to floats. If you write a number x as a decimal, then math.trunc() returns the integer part to the left of the decimal point. Its output has class int.

for x in lst: 
    print("math.trunc(" + str(x) + "): " + str(math.trunc(x)))

Output:

math.trunc(1.5): 1
math.trunc(3): 3
math.trunc(-6.2): -6
math.trunc(3.141592653589793): 3
math.trunc(0): 0
math.trunc(2.71828): 2
math.trunc(29.0): 29
math.trunc(-91.312): -91
math.trunc(1.4142135623730951): 1

Compare the above values to the values given by int():

for x in lst: 
    print("int(" + str(x) + "): " + str(int(x)))

Output:

int(1.5): 1
int(3): 3
int(-6.2): -6
int(3.141592653589793): 3
int(0): 0
int(2.71828): 2
int(29.0): 29
int(-91.312): -91
int(1.4142135623730951): 1

There is no difference between the two functions when applied to floats.

The modf Function.

math.modf(float)

Finally, in mathematical terms, the modf function takes a real number x and returns the ordered pair (r,n) where r,n are respectively the fractional and integer part from before. Observe that the r+n=x.

In Python, math.modf() takes in a float and returns a class tuple object. Each element in the tuple are floats:

for x in lst: 
    print("math.modf(" + str(x) + "): " + str(math.modf(x)))

Output:

math.modf(1.5): (0.5, 1.0)
math.modf(3): (0.0, 3.0)
math.modf(-6.2): (-0.20000000000000018, -6.0)
math.modf(3.141592653589793): (0.14159265358979312, 3.0)
math.modf(0): (0.0, 0.0)
math.modf(2.71828): (0.71828, 2.0)
math.modf(29.0): (0.0, 29.0)
math.modf(-91.312): (-0.3119999999999976, -91.0)
math.modf(1.4142135623730951): (0.41421356237309515, 1.0)