The Scenario
Your math-heavy code is running fine β until it isn't. A machine learning loss function, a financial model, a stats calculation. Something blows up with:
OverflowError: math range error
Nine times out of ten, it traces back to something like this:
import math
math.exp(1000)
# OverflowError: math range error
Or it's buried three layers deep in a longer calculation where one intermediate result quietly got enormous.
Why This Happens
Python's math module wraps C's double β a 64-bit float with a ceiling of roughly 1.8 Γ 10^308. math.exp(709) produces ~8.2Γ10^307, which fits. math.exp(710) would produce ~2.2Γ10^308 β and that's over the limit. Rather than silently returning inf, Python raises OverflowError: math range error.
The usual suspects:
math.exp(x)wherex > ~709math.cosh(),math.sinh()with large inputs- Raising a large float to a large power
- Intermediate values in iterative algorithms (e.g., softmax, log-sum-exp)
import math
math.exp(710) # OverflowError
math.cosh(800) # OverflowError
10.0 ** 309 # OverflowError
Quick Fix: Use math.inf or Clamp the Input
Need the code to stop crashing and inf is an acceptable result? Catch the exception:
import math
def safe_exp(x):
try:
return math.exp(x)
except OverflowError:
return math.inf
print(safe_exp(1000)) # inf
Or clamp the input before it ever reaches exp:
import math
MAX_EXP = 709.78 # math.exp(709.78) is just under the float64 limit
def safe_exp(x):
return math.exp(min(x, MAX_EXP))
print(safe_exp(1000)) # 8.218407461554972e+307
Permanent Fix: Switch to numpy or decimal
Option 1 β numpy (most common for numerical work)
NumPy's np.exp() returns inf quietly, no exception thrown:
import numpy as np
np.exp(1000) # inf (no error)
np.exp(710) # inf
np.exp(700) # 1.0142320547350045e+304
Want to suppress the overflow warning too? Use errstate:
import numpy as np
with np.errstate(over='ignore'):
result = np.exp(np.array([700, 800, 1000]))
print(result) # [1.01423205e+304 inf inf]
Option 2 β mpmath for arbitrary precision
Sometimes inf isn't good enough β you need the actual number. mpmath handles arbitrarily large values:
from mpmath import mp, exp
mp.dps = 50 # 50 decimal places of precision
result = exp(1000)
print(result)
# 5.0751411135066437985915844766989085095016671145491e+434
Option 3 β Python's built-in decimal
No external library needed. The standard decimal module handles this too:
from decimal import Decimal, getcontext
getcontext().prec = 50
result = Decimal(1000).exp()
print(result)
# 5.075141113506643798591584476698908509501667114549E+434
Special Case: Softmax and Log-Sum-Exp Overflow
Implementing softmax from scratch? This is where the error bites most often:
import math
def softmax_naive(scores):
exps = [math.exp(s) for s in scores] # OverflowError if any s > 709
total = sum(exps)
return [e / total for e in exps]
softmax_naive([1000, 2000, 3000]) # OverflowError
Subtract the max before exponentiating. It's a well-known numerical stability trick β the math works out identically, but the numbers stay manageable:
import math
def softmax_stable(scores):
m = max(scores)
exps = [math.exp(s - m) for s in scores]
total = sum(exps)
return [e / total for e in exps]
print(softmax_stable([1000, 2000, 3000]))
# [0.0, 0.0, 1.0] β no error
Same idea applies to log-sum-exp:
import math
def logsumexp(values):
m = max(values)
return m + math.log(sum(math.exp(v - m) for v in values))
print(logsumexp([1000, 2000, 3000])) # 3000.0 β no error
Checking Float Limits
Curious where exactly the ceiling sits on your system? Two lines tells you everything:
import sys
print(sys.float_info.max) # 1.7976931348623157e+308
print(sys.float_info.min) # 2.2250738585072014e-308
import math
print(math.log(sys.float_info.max)) # 709.782... β that's your exp() ceiling
Verification
Run this after applying your fix to confirm the original crash is gone:
import math
import numpy as np
# Before fix:
try:
math.exp(1000)
except OverflowError as e:
print(f"Still broken: {e}")
# After fix with numpy:
result = np.exp(1000)
print(f"numpy result: {result}") # numpy result: inf
print(f"Is inf: {np.isinf(result)}") # Is inf: True
# After fix with stable softmax:
scores = [1000, 2000, 3000]
result = softmax_stable(scores)
print(f"Softmax OK: {result}") # [0.0, 0.0, 1.0]
Quick Reference
- max safe input for math.exp(): ~709.78
- Want inf instead of error: use
numpy.exp() - Need exact large value: use
mpmath.exp()ordecimal.Decimal.exp() - Softmax/log-sum-exp overflow: subtract max before exp β always
- Suppress numpy overflow warnings:
np.errstate(over='ignore')

