python/cpython · error · ValueError
cannot round a NaN
Error message
cannot round a NaN
What it means
round(Decimal('NaN')) — the one-argument form — raises ValueError('cannot round a NaN') because there is no nearest integer to a NaN. The two-argument form instead delegates to quantize, which returns NaN under signal-based semantics, so only the one-arg form raises here.
Source
Thrown at Lib/_pydecimal.py:1844
Decimal('1E+2')
>>> with localcontext(ExtendedContext):
... round(Decimal('-Infinity'), 37)
... round(Decimal('sNaN123'), 0)
Decimal('NaN')
Decimal('NaN123')
"""
if n is not None:
# two-argument form: use the equivalent quantize call
if not isinstance(n, int):
raise TypeError('Second argument to round should be integral')
exp = _dec_from_triple(0, '1', -n)
return self.quantize(exp)
# one-argument form
if self._is_special:
if self.is_nan():
raise ValueError("cannot round a NaN")
else:
raise OverflowError("cannot round an infinity")
return int(self._rescale(0, ROUND_HALF_EVEN))
def __floor__(self):
"""Return the floor of self, as an integer.
For a finite Decimal instance self, return the greatest
integer n such that n <= self. If self is infinite or a NaN
then a Python exception is raised.
"""
if self._is_special:
if self.is_nan():
raise ValueError("cannot round a NaN")
else:
raise OverflowError("cannot round an infinity")
return int(self._rescale(0, ROUND_FLOOR))View on GitHub (pinned to bc6749cc3b)
Solutions
- Guard with value.is_nan() before rounding; render 'NaN' literally or substitute a policy value
- Filter non-finite values upstream of formatting code
- In the two-argument form round(d, n) NaN propagates instead — choose the form matching your error strategy
Example fix
// before shown = round(v) # ValueError when v is NaN // after shown = 'NaN' if v.is_nan() else round(v)
Defensive patterns
Strategy: validation
Validate before calling
def safe_round1(d):
if d.is_nan():
raise ValueError(f'cannot round NaN {d}')
return round(d) Type guard
def is_roundable(d) -> bool:
return not d._is_special Try / catch
try:
n = round(d)
except ValueError:
n = 0 # NaN policy
except OverflowError:
raise OverflowError(f'cannot round {d}') from None Prevention
- Guard all one-arg round()/int()/floor()/ceil() calls with a single _is_special check
- Filter NaN sentinels at ingestion before formatting code
- Note the two-arg round(d, n) propagates NaN instead of raising — pick deliberately
When it happens
Trigger: round(Decimal('NaN')); round(Decimal('sNaN')); round(d) where d parsed from 'NaN' text in data.
Common situations: Display formatting that rounds values for output, hit by NaN sentinels from data feeds; round(x) used as a quick 'nearest int' on mixed-quality data.
Related errors
- cannot convert NaN to integer ratio
- Cannot convert signaling NaN to float
- Cannot convert NaN to integer
- Second argument to round should be integral
- cannot round an infinity
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/8881c898e394216a.
Report an issue: GitHub.