python/cpython · error · ValueError

argument must be a multiple of 32, with a maximum of {IEEE_C

Error message

argument must be a multiple of 32, with a maximum of {IEEE_CONTEXT_MAX_BITS}

What it means

Raised by decimal.IEEEContext(bits) when the requested bit width is not a positive multiple of 32 or exceeds IEEE_CONTEXT_MAX_BITS (999999999 on 64-bit builds). IEEEContext builds a Context matching an IEEE 754 interchange format (32, 64, 128, ... bit), and precision/Emax/Emin are derived from bits//32 and bits//16, so arbitrary widths would produce nonsensical contexts. It is a ValueError thrown before any context is constructed.

Source

Thrown at Lib/_pydecimal.py:434

    """
    if ctx is None:
        ctx = getcontext()
    ctx_manager = _ContextManager(ctx)
    for key, value in kwargs.items():
        if key not in _context_attributes:
            raise TypeError(f"'{key}' is an invalid keyword argument for this function")
        setattr(ctx_manager.new_context, key, value)
    return ctx_manager


def IEEEContext(bits, /):
    """
    Return a context object initialized to the proper values for one of the
    IEEE interchange formats.  The argument must be a multiple of 32 and less
    than IEEE_CONTEXT_MAX_BITS.
    """
    if bits <= 0 or bits > IEEE_CONTEXT_MAX_BITS or bits % 32:
        raise ValueError("argument must be a multiple of 32, "
                         f"with a maximum of {IEEE_CONTEXT_MAX_BITS}")

    ctx = Context()
    ctx.prec = 9 * (bits//32) - 2
    ctx.Emax = 3 * (1 << (bits//16 + 3))
    ctx.Emin = 1 - ctx.Emax
    ctx.rounding = ROUND_HALF_EVEN
    ctx.clamp = 1
    ctx.traps = dict.fromkeys(_signals, False)

    return ctx


##### Decimal class #######################################################

# Do not subclass Decimal from numbers.Real and do not register it as such
# (because Decimals are not interoperable with floats).  See the notes in
# numbers.py for more detail.

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Pass one of the standard interchange widths: 32, 64, 128, 256, ... (all positive multiples of 32)
  2. If the width is computed, round/validate it first: bits = max(32, ((bits + 31) // 32) * 32)
  3. Check against decimal.IEEE_CONTEXT_MAX_BITS before calling if the value can be huge

Example fix

// before
ctx = IEEEContext(16 * precision)  # precision=4 -> 64 ok, precision=3 -> 48 fails? no: 48 is multiple of 32? no -> ValueError

// after
bits = max(32, ((16 * precision + 31) // 32) * 32)
ctx = IEEEContext(bits)
Defensive patterns

Strategy: validation

Validate before calling

import decimal

def valid_ieee_bits(bits):
    return (isinstance(bits, int)
            and bits > 0
            and bits % 32 == 0
            and bits <= decimal.IEEE_CONTEXT_MAX_BITS)

# before calling:
# assert valid_ieee_bits(bits); ctx = decimal.IEEEContext(bits)

Type guard

def is_ieee_width(bits) -> bool:
    return isinstance(bits, int) and 0 < bits <= __import__('decimal').IEEE_CONTEXT_MAX_BITS and bits % 32 == 0

Try / catch

try:
    ctx = decimal.IEEEContext(bits)
except ValueError as e:
    raise ValueError(f'bad IEEE width {bits!r}: use 32/64/128/...') from e

Prevention

When it happens

Trigger: IEEEContext(100) (not a multiple of 32); IEEEContext(0) or IEEEContext(-32) (bits <= 0); IEEEContext(10**9) (exceeds IEEE_CONTEXT_MAX_BITS). Valid calls are IEEEContext(32), IEEEContext(64), IEEEContext(128), IEEEContext(256), ...

Common situations: Dynamically computing a bit width from user input or a precision setting (e.g. IEEEContext(16 * precision) yielding 48 or 80), or confusing decimal digit precision with IEEE format width (passing 7 for 'single precision' instead of 32).

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/031fe139fd501524. Report an issue: GitHub.