Skip to content
Happy Programming Guide
Start learning
Python

Understanding the Value of Pi in Python

Where to get pi in Python, why math.pi is a float rather than the exact number, and how to get more decimal places when you genuinely need them.

A laptop computer on a table

Pi in Python is math.pi. It gives you about fifteen decimal places, which is enough to calculate the circumference of the Earth to within a fraction of a millimetre. This guide covers where to find it, why it is not exact, how to get more digits when you genuinely need them, and the floating-point behaviour that surprises people.

Where to get it#

Python
import math

print(math.pi)      # 3.141592653589793
print(math.tau)     # 6.283185307179586 - two pi
print(math.e)       # 2.718281828459045
Python
import numpy as np
print(np.pi)        # same value, convenient inside array code

import cmath
print(cmath.pi)     # same, for complex maths

All three are the same double-precision number. Use math.pi unless you are already working with NumPy.

Why it is not exact#

Pi is irrational: its decimal expansion never ends and never repeats. No finite representation can be exact. Python stores it as a 64-bit float, which gives roughly fifteen to seventeen significant decimal digits.

Python
print(f"{math.pi:.20f}")
# 3.14159265358979311600

The true value continues 3.14159265358979323846… so the stored value diverges around the seventeenth digit. That sounds tiny and it is: fifteen digits of pi is enough to compute the circumference of the observable universe to within the width of an atom. For engineering, science and anything you are likely to build, math.pi is not the limiting factor.

Using it#

Python
import math


def circle_area(radius):
    return math.pi * radius ** 2


def circle_circumference(radius):
    return 2 * math.pi * radius


def sphere_volume(radius):
    return (4 / 3) * math.pi * radius ** 3


print(round(circle_area(5), 4))            # 78.5398
print(round(circle_circumference(5), 4))   # 31.4159

math.tau is two pi, and it makes circumference formulas read more naturally:

Python
circumference = math.tau * radius          # instead of 2 * math.pi * radius

Degrees and radians#

This is where real bugs come from. Every trigonometric function in Python takes radians, not degrees:

Python
import math

print(math.sin(90))                    # 0.8939... - 90 radians, not degrees
print(math.sin(math.radians(90)))      # 1.0 - correct

print(math.degrees(math.pi))           # 180.0
print(math.radians(180))               # 3.141592653589793

Why sin(pi) is not zero#

Python
print(math.sin(math.pi))
# 1.2246467991473532e-16

Mathematically it should be zero. But math.pi is very slightly not pi, so you are taking the sine of a number a hair away from pi, and the answer is a hair away from zero.

The practical consequence is that you should never test floating-point results for exact equality:

Python
print(math.sin(math.pi) == 0)                    # False
print(math.isclose(math.sin(math.pi), 0, abs_tol=1e-9))   # True
print(round(math.sin(math.pi), 10))              # 0.0

math.isclose is the right tool. Note the abs_tol argument — when comparing against zero, relative tolerance alone does not work, because everything is infinitely far from zero in relative terms.

More decimal places#

If you genuinely need more — usually for teaching, puzzles or number theory rather than physics:

Python
from decimal import Decimal, getcontext

getcontext().prec = 50

# Chudnovsky-style series converge fast, but the simplest route is
# a known high-precision literal for a fixed number of digits:
pi_50 = Decimal("3.1415926535897932384626433832795028841971693993751")

print(pi_50 * Decimal(2))

For computed arbitrary precision, mpmath does it properly:

Python
from mpmath import mp

mp.dps = 100                  # decimal places
print(mp.pi)
print(mp.sin(mp.pi))          # far closer to zero
Terminal
python -m pip install mpmath

Calculating pi yourself#

Worth doing once, to see how slowly some series converge:

Python
def leibniz(terms):
    """pi/4 = 1 - 1/3 + 1/5 - 1/7 + ..."""
    total = 0.0
    for k in range(terms):
        total += (-1) ** k / (2 * k + 1)
    return 4 * total


print(leibniz(1_000))       # 3.140592...  - two correct digits
print(leibniz(1_000_000))   # 3.141591...  - five correct digits

A million terms for five digits. The Nilakantha series does much better for the same effort:

Python
def nilakantha(terms):
    total = 3.0
    sign = 1
    for k in range(1, terms + 1):
        n = 2 * k
        total += sign * 4 / (n * (n + 1) * (n + 2))
        sign = -sign
    return total


print(nilakantha(100))      # accurate to about ten digits

The lesson generalises well beyond pi: two algorithms that both give the right answer can differ enormously in how much work they need to get there.

Formatting for display#

Python
import math

print(f"{math.pi:.2f}")       # 3.14
print(f"{math.pi:.5f}")       # 3.14159
print(f"{math.pi:10.4f}")     # padded to width 10
print(f"{math.pi:.3e}")       # 3.142e+00
print(round(math.pi, 4))      # 3.1416 - a number, not a string

An f-string produces text for display; round produces a number you can keep calculating with. Round for output only — rounding intermediate values accumulates error.

Questions people ask#

Is math.pi the same as numpy.pi?

Yes, the same double-precision value. NumPy provides it so array code does not need a second import.

Can I redefine math.pi?

You can assign to it, and you should not. Anything else importing math in the same process sees your change, which is a spectacularly confusing bug to leave for someone.

How many digits do I actually need?

NASA uses around fifteen for interplanetary navigation. If fifteen is enough to land a probe on another planet, it is enough for your program.

Why does 0.1 + 0.2 not equal 0.3?

The same reason pi is inexact: binary floating point cannot represent some decimal fractions exactly. Compare with math.isclose, or use decimal when exactness matters, as it does for money.

Where to go next#

What is an algorithm? Why one series needed a million termsRead next

Keep reading

Python

Python Best Practices

Naming, structure, error handling, virtual environments, type hints and testing — the habits that make Python code easy to come back to.

5 min read

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *