TheAlgorithms/Python · error · ValueError

Exponent must be a non-negative integer

Error message

Exponent must be a non-negative integer

What it means

binary_exp_recursive(base, exponent) computes base**exponent by repeated squaring and rejects negative exponents with ValueError('Exponent must be a non-negative integer'), because the algorithm (and its int-based halving) has no reciprocal branch.

Source

Thrown at maths/binary_exponentiation.py:41

    >>> binary_exp_recursive(11, 13)
    34522712143931
    >>> binary_exp_recursive(-1, 3)
    -1
    >>> binary_exp_recursive(0, 5)
    0
    >>> binary_exp_recursive(3, 1)
    3
    >>> binary_exp_recursive(3, 0)
    1
    >>> binary_exp_recursive(1.5, 4)
    5.0625
    >>> binary_exp_recursive(3, -1)
    Traceback (most recent call last):
        ...
    ValueError: Exponent must be a non-negative integer
    """
    if exponent < 0:
        raise ValueError("Exponent must be a non-negative integer")

    if exponent == 0:
        return 1

    if exponent % 2 == 1:
        return binary_exp_recursive(base, exponent - 1) * base

    b = binary_exp_recursive(base, exponent // 2)
    return b * b


def binary_exp_iterative(base: float, exponent: int) -> float:
    """
    Computes a^b iteratively, where a is the base and b is the exponent

    >>> binary_exp_iterative(3, 5)
    243
    >>> binary_exp_iterative(11, 13)

View on GitHub (pinned to f5988cc097)

Solutions

  1. Use a nonnegative exponent; for negative powers compute 1 / binary_exp_recursive(base, -exponent) yourself.
  2. Clamp or validate the exponent at the call site.
  3. Use Python's ** operator if you need full negative-exponent support.

Example fix

# before
result = binary_exp_recursive(2, -3)

# after
result = 1 / binary_exp_recursive(2, 3)  # 0.125
Defensive patterns

Strategy: validation

Validate before calling

if exponent < 0:
    result = 1 / binary_exp_recursive(base, -exponent)
else:
    result = binary_exp_recursive(base, exponent)

Type guard

def is_nonneg_int(e: object) -> bool:
    return isinstance(e, int) and e >= 0

Prevention

When it happens

Trigger: binary_exp_recursive(3, -1); any negative exponent from modular-inverse style code or from 0-defaulted counters decremented below zero.

Common situations: Porting math.pow habits (negative exponents allowed there); computing reciprocals; exponent derived as (a - b) where b can exceed a.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/6e273344942b73c4. Report an issue: GitHub.