math library
The math module extends Python's built-in arithmetic with functions it doesn't provide directly — square roots, rounding modes, constants like pi, and logarithms.
Setup
math ships with Python's standard library — nothing to install. The whole module is used through the math. prefix, so a plain import is all you need.
import math
| Function/constant | Returns | Example |
|---|---|---|
floor(x) |
Largest integer <= x |
floor(6.75) → 6 |
ceil(x) |
Smallest integer >= x |
ceil(6.75) → 7 |
sqrt(x) |
Square root of x |
sqrt(16) → 4.0 |
pow(x, y) |
x raised to y, as a float |
pow(4, 2) → 16.0 |
pi |
The constant π | 3.141592653589793 |
log(x), log2(x), log10(x) |
Logarithm of x, in the given base |
log2(64) → 6.0 |
isclose(a, b) |
Whether a and b are close enough to count as equal |
isclose(0.1 + 0.2, 0.3) → True |
Rounding
floor() and ceil() round down and up to the nearest integer. Unlike the built-in round(), they never round to the nearest value — floor() always goes down, ceil() always goes up.
import math
lengths_ft = [3.5, 12, 4.75]
avg = sum(lengths_ft) / len(lengths_ft)
print(avg)
print(math.floor(avg))
print(math.ceil(avg))
trunc
Chops off the decimal part instead of rounding toward a direction — the same as floor() for a positive number, but different for a negative one, where it rounds toward zero instead of down.
math.trunc(6.75) # 6 — same as floor here
math.trunc(-6.75) # -6 — floor(-6.75) would be -7
Run a rounding example
All the examples above, combined into one script:
import math
lengths_ft = [3.5, 12, 4.75]
avg = sum(lengths_ft) / len(lengths_ft)
print(avg)
print(math.floor(avg))
print(math.ceil(avg))
import math
print(math.trunc(6.75))
print(math.trunc(-6.75))
Roots and powers
sqrt() finds a square root — useful anywhere the Pythagorean theorem shows up, like the diagonal brace of a square enclosure.
import math
side_ft = 4
diagonal = math.sqrt(side_ft ** 2 + side_ft ** 2)
print(diagonal)
pow
Raises a number to a power, same idea as the ** operator — but math.pow() always returns a float, even when the inputs are whole numbers, while ** keeps an integer result an int.
side_ft ** 2 # 16 — an int
math.pow(side_ft, 2) # 16.0 — always a float
Integer square roots with isqrt
math.sqrt() always returns a float, even for a perfect square. math.isqrt() works on integers only and rounds down, avoiding any floating-point rounding error.
math.sqrt(50) # 7.0710678118654755
math.isqrt(50) # 7 — rounded down, exact
Run a roots and powers example
All the examples above, combined into one script:
import math
side_ft = 4
diagonal = math.sqrt(side_ft ** 2 + side_ft ** 2)
print(diagonal)
print(side_ft ** 2)
print(math.pow(side_ft, 2))
Constants
math.pi is the constant π, accurate to the precision of a float — no need to type out 3.14159... by hand.
import math
radius_ft = 3
circumference = 2 * math.pi * radius_ft
print(circumference)
inf and nan
math.inf is a value larger than any number, useful as a starting point when searching for a minimum. math.nan ("not a number") represents an undefined result, like 0 / 0 in floating-point math — check for it with math.isnan(), since nan == nan is always False.
smallest = math.inf
for length in [5, 12, 3.5]:
if length < smallest:
smallest = length
smallest # 3.5
math.isnan(math.nan) # True
Run a constants example
All the examples above, combined into one script:
import math
radius_ft = 3
circumference = 2 * math.pi * radius_ft
print(circumference)
import math
smallest = math.inf
for length in [5, 12, 3.5]:
if length < smallest:
smallest = length
print(smallest)
print(math.isnan(math.nan))
Logarithms
log2() is the inverse of doubling — how many times a starting value has to double to reach a target. A breeding program tracking how many generations it takes to go from 2 snakes to 64 is a direct fit.
import math
starting = 2
population = 64
generations = math.log2(population / starting)
print(generations)
log() and log10() work the same way in base e and base 10, and exp() reverses log() — raising e to a power.
math.log10(1000) # 3.0
math.exp(1) # 2.718281828459045 — the same as math.e
Run a logarithms example
All the examples above, combined into one script:
import math
starting = 2
population = 64
generations = math.log2(population / starting)
print(generations)
print(math.log10(1000))
print(math.exp(1))
Comparing floats
Floating-point math loses tiny amounts of precision, so two values that should be mathematically equal often aren't exactly equal in code. math.isclose() checks whether two numbers are close enough to count as equal instead of comparing them bit for bit.
import math
0.1 + 0.2 == 0.3 # False — a floating-point rounding artifact
math.isclose(0.1 + 0.2, 0.3) # True
Never compare floats with ==
0.1 + 0.2 is actually 0.30000000000000004 under the hood — every float is stored as a binary approximation, and 0.1 can't be represented exactly in binary any more than 1/3 can be written exactly in decimal. == compares that approximation exactly, so it fails in cases that look like they should match. math.isclose() is the fix any time float results are compared, not just when the numbers came from a fraction like this one.
Run a comparing floats example
All the examples above, combined into one script:
import math
print(0.1 + 0.2 == 0.3)
print(math.isclose(0.1 + 0.2, 0.3))