OverflowError: math range error (tested)

OverflowError: math range error means a math function produced a number too large for a float. We measured where the limit is on Python 3.13.5, why the same overflow has three different messages, and the stable rewrites (sigmoid, log-sum-exp) that avoid it.

1. Where the limit is, and which operations raise

import math

tests = {
    "math.exp(709)": lambda: math.exp(709),
    "math.exp(710)": lambda: math.exp(710),
    "math.pow(10, 309)": lambda: math.pow(10, 309),
    "10.0 ** 309": lambda: 10.0 ** 309,
    "10 ** 309 (int)": lambda: len(str(10 ** 309)),
    "float(10 ** 309)": lambda: float(10 ** 309),
    "1e308 * 10": lambda: 1e308 * 10,
    "math.exp(-1000)": lambda: math.exp(-1000),
}
for label, fn in tests.items():
    try:
        print(f"{label:20} -> {fn()}")
    except OverflowError as e:
        print(f"{label:20} -> OverflowError: {e}")

Output:

math.exp(709)        -> 8.218407461554972e+307
math.exp(710)        -> OverflowError: math range error
math.pow(10, 309)    -> OverflowError: math range error
10.0 ** 309          -> OverflowError: (34, 'Numerical result out of range')
10 ** 309 (int)      -> 310
float(10 ** 309)     -> OverflowError: int too large to convert to float
1e308 * 10           -> inf
math.exp(-1000)      -> 0.0

Measured on Python 3.13.5: a float tops out near 1.8e308, so math.exp() works up to 709 and raises math range error at 710. The same overflow gives three different messages depending on the operation: math range error from the math module, (34, 'Numerical result out of range') from float **, and int too large to convert to float when a big int becomes a float. Two cases don't raise at all: plain float multiplication silently returns inf, and math.exp(-1000) silently underflows to 0.0. Python ints never overflow; 10 ** 309 is fine until you convert it.

2. The classic: sigmoid / logistic with large negative input

import math

def sigmoid(x):
    return 1 / (1 + math.exp(-x))

def sigmoid_stable(x):
    if x >= 0:
        return 1 / (1 + math.exp(-x))
    z = math.exp(x)
    return z / (1 + z)

for x in [5, -745, -800]:
    try:
        a = sigmoid(x)
    except OverflowError as e:
        a = f"OverflowError: {e}"
    print(x, "|", a, "|", sigmoid_stable(x))

Output:

5 | 0.9933071490757153 | 0.9933071490757153
-745 | OverflowError: math range error | 5e-324
-800 | OverflowError: math range error | 0.0

Measured: the textbook 1 / (1 + exp(-x)) raises for x = -745, because exp(745) overflows even though the true answer is just tiny. Branching on the sign so exp() only ever sees a non-positive argument never overflows.

3. Sums of exponentials: subtract the max first

import math

xs = [1000, 1001, 1002]
try:
    print(math.log(sum(math.exp(x) for x in xs)))
except OverflowError as e:
    print("naive:", "OverflowError:", e)

m = max(xs)
print("log-sum-exp:", m + math.log(sum(math.exp(x - m) for x in xs)))

from decimal import Decimal
print("Decimal:", Decimal(1000).exp())

Output:

naive: OverflowError: math range error
log-sum-exp: 1002.4076059644444
Decimal: 1.970071114017046993888879352E+434

Measured: log(sum(exp(x))) overflows for values around 1000; the log-sum-exp trick (factor out exp(max)) gives 1002.4076... with no overflow. Softmax needs the same trick. If you need the huge number itself, Decimal has a far larger exponent range: Decimal(1000).exp() returned about 1.97E+434.

4. Checklist

Frequently asked questions

What causes OverflowError: math range error in Python?

A math function's result is too big for a float (max about 1.8e308). We measured math.exp(709) working and math.exp(710) raising.

Why does 1 / (1 + math.exp(-x)) raise OverflowError?

For large negative x, math.exp(-x) overflows. We measured it failing at x = -745; a sign-branched stable sigmoid returned 5e-324 instead.

Why does OverflowError say (34, 'Numerical result out of range')?

That's the message from float ** (errno 34 is ERANGE). We measured 10.0 ** 309 raising it, while math.pow(10, 309) says math range error.

Does Python float multiplication raise OverflowError?

No. We measured 1e308 * 10 returning inf silently; check math.isinf() if that matters.

Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on x86-64 Linux: math.exp, math.pow, float and int powers, int-to-float conversion, float multiplication and underflow, a naive and a stable sigmoid, and naive vs log-sum-exp with a Decimal comparison. Every block was run verbatim and its output pasted from that run. PlainHeaders is our extension; everything else here is built-in Python.