How to Use the pow() Method in Python

The pow() method in Python raises a number to a power: pow(base, exp) gives the same result as base ** exp. Its extra trick is a third argument, pow(base, exp, mod), which computes the remainder efficiently without building the huge intermediate number:

pow(2, 10)          # 1024
pow(7, 1_000_003, 1_000_000_007)   # fast modular power

I checked each result type and error message on Python 3.12.5, since pow() returns ints, floats or even complex numbers depending on the inputs.

You’ll see pow vs ** vs math.pow, what type comes back, compound interest, three-argument modular pow and its speed, modular inverses, and when results overflow.

How pow() compares with ** and math.pow()

For two arguments, pow() and ** behave identically. math.pow() always converts to float. The type of the result depends on the inputs:

import math

print(pow(2, 10), 2 ** 10, math.pow(2, 10))
print(pow(2, -2))                 # negative exponent -> float
print(pow(9, 0.5))                # fractional exponent -> square root
print(pow(0, 0))                  # defined as 1
print(pow(-8, 1/3))               # negative base, fractional exponent -> complex

Output:

1024 1024 1024.0
0.25
3.0
1
(1.0000000000000002+1.7320508075688772j)
Command Prompt output of Python pow returning an int, a float for a negative exponent, a square root, 1 for pow(0, 0) and a complex number
pow(2, 10) gives 1024 as an int, a negative exponent gives 0.25, pow(0, 0) is 1, and a negative base with 1/3 gives a complex number.

The complex result surprises people who expect -2. Squaring specifically is covered in how to square a number in Python.

Calculate compound interest with pow()

Growth over time is the everyday use: balance = principal * pow(1 + rate, years). Here’s $10,000 at 4.5% a year:

principal = 10_000.00          # USD
rate = 0.045                   # 4.5% a year
for years in (1, 5, 10, 30):
    balance = principal * pow(1 + rate, years)
    print(f"after {years:>2} yr: ${balance:>10,.2f}")

monthly = principal * pow(1 + rate / 12, 12 * 10)
print(f"10 years, compounded monthly: ${monthly:,.2f}")

Output:

after  1 yr: $ 10,450.00
after  5 yr: $ 12,461.82
after 10 yr: $ 15,529.69
after 30 yr: $ 37,453.18
10 years, compounded monthly: $15,669.93
Command Prompt output of Python pow calculating compound interest on $10,000 at 4.5% over 1, 5, 10 and 30 years
The balance grows from about $10,450 after one year to over $37,000 after 30, and monthly compounding beats yearly over 10 years.

Round only when you display money. For more on rounding, see rounding numbers to 2 decimal places.

What does the third argument of pow() do?

pow(b, e, m) returns (b ** e) % m, but it reduces the number at every step instead of computing b ** e first. That’s how cryptography code handles exponents with millions of digits:

import math
import time

base, exp, mod = 7, 1_000_003, 1_000_000_007

start = time.perf_counter()
fast = pow(base, exp, mod)
t_fast = time.perf_counter() - start

start = time.perf_counter()
slow = (base ** exp) % mod
t_slow = time.perf_counter() - start

print("same answer:", fast == slow, fast)
print(f"pow(b, e, m) was about {t_slow / t_fast:,.0f}x faster than (b ** e) % m")
print(f"7 ** 1000003 has {math.floor(exp * math.log10(base)) + 1:,} digits")   # str() would hit the 4,300-digit limit

Output:

same answer: True 842703477
pow(b, e, m) was about 64,157x faster than (b ** e) % m
7 ** 1000003 has 845,101 digits
Command Prompt output of Python three-argument pow matching (b ** e) % m and running many times faster
Both expressions give the same remainder, but pow(b, e, m) finishes many times faster because 7 ** 1000003 has about 845,000 digits.

The speed-up grows with the exponent. Printing that number with str() raises ValueError, because Python limits int-to-string conversion to 4,300 digits by default. For the plain ** operator and its rules, see exponents in Python.

Find a modular inverse with pow(b, -1, m)

Since Python 3.8, a negative exponent with a modulus gives the modular inverse. It raises an error when no inverse exists:

inv = pow(3, -1, 11)              # x such that 3 * x % 11 == 1  (Python 3.8+)
print(inv, (3 * inv) % 11)

try:
    pow(4, -1, 8)                 # 4 and 8 share a factor: no inverse
except ValueError as err:
    print("ValueError:", err)

try:
    pow(2.5, 2, 7)                # three-argument form needs integers
except TypeError as err:
    print("TypeError:", err)

Output:

4 1
ValueError: base is not invertible for the given modulus
TypeError: pow() 3rd argument not allowed unless all arguments are integers
Command Prompt output of Python pow(3, -1, 11) returning a modular inverse, a ValueError when none exists and a TypeError for floats
pow(3, -1, 11) returns 4 because 3 times 4 leaves remainder 1; pow(4, -1, 8) raises ValueError, and a float base raises TypeError.

The three-argument form only accepts integers. That’s the main reason pow() exists alongside **.

pow() overflow with floats and math.pow

Integer results never overflow; they just get longer. Float results do, and very small floats quietly become zero:

import math

big = pow(10, 400)
print(len(str(big)), "digits, exact int")

for label, fn in [("pow(10.0, 400)", lambda: pow(10.0, 400)), ("math.pow(10, 400)", lambda: math.pow(10, 400))]:
    try:
        fn()
    except OverflowError as err:
        print(f"{label}: OverflowError: {err}")

print(pow(10.0, -400))            # underflow quietly gives 0.0

Output:

401 digits, exact int
pow(10.0, 400): OverflowError: (34, 'Result too large')
math.pow(10, 400): OverflowError: math range error
0.0

If you need huge exact values, keep them as ints. For roots, which are fractional powers, see square roots in Python.

pow(), ** and math.pow() compared

Featurepow()**math.pow()
Int result for intsYesYesNo (float)
Modulus argumentYesNoNo
Modular inversepow(b, -1, m)NoNo
Huge int resultsExactExactOverflowError
Negative base, fractional expcomplexcomplexValueError

For a single digit-level task like summing squared digits, see the sum of squares of digits.

Looking for more math in Python? These are good next steps:

Frequently asked questions

What does pow() do in Python?

pow(base, exp) returns base raised to exp, like base ** exp; pow(base, exp, mod) returns the result modulo mod.

What is the difference between pow() and math.pow()?

Built-in pow keeps ints exact and accepts a modulus. math.pow always returns a float and can overflow.

Why does pow(-8, 1/3) return a complex number?

A negative base with a fractional exponent has no real result in floating point, so Python returns the principal complex root.

How do I compute a modular inverse in Python?

Use pow(b, -1, m) on Python 3.8 or later. It raises ValueError when no inverse exists.

Is pow(b, e, m) faster than (b ** e) % m?

Yes, often by orders of magnitude, because it never builds the full power.

Where is pow() documented?

See pow() in the Python docs.