Skip to content

Commit 6c3a559

Browse files
committed
fix(intcomma): handle scientific notation for large/small floats
Fixes #431 - intcomma() returns scientific notation for floats of 1e16 and above (and very small floats like 1e-5), with no commas added. Root cause: Python's repr() switches to scientific notation for floats with magnitude >= 1e15 or <= 1e-5. The f"{value:,}" format specifier uses repr() internally, so comma formatting is never applied to the exponent form. Fix: When ndigits is None and the float is a whole number, format as int to avoid trailing .0. When the float would be formatted in scientific notation, use Decimal for a proper decimal representation before applying commas.
1 parent 6ed367f commit 6c3a559

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

‎src/humanize/number.py‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,26 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
197197
if ndigits is not None:
198198
result = f"{value:,.{ndigits}f}"
199199
else:
200-
result = f"{value:,}"
200+
if isinstance(value, float) and value == int(value):
201+
# Whole-number float: format as int to avoid trailing .0
202+
result = f"{int(value):,}"
203+
elif isinstance(value, float) and value != 0 and (abs(value) >= 1e15 or abs(value) <= 1e-5):
204+
# Python repr uses scientific notation for very large/small floats,
205+
# which breaks the , format specifier. Use Decimal for proper formatting.
206+
from decimal import Decimal
207+
d = Decimal(str(value))
208+
formatted = f"{d:f}"
209+
if "." in formatted:
210+
int_part, dec_part = formatted.split(".")
211+
dec_part = dec_part.rstrip("0")
212+
if dec_part:
213+
result = f"{int(int_part):,}.{dec_part}"
214+
else:
215+
result = f"{int(int_part):,}"
216+
else:
217+
result = f"{int(formatted):,}"
218+
else:
219+
result = f"{value:,}"
201220
if thousands_sep != "," or decimal_sep != ".":
202221
result = result.translate(str.maketrans(",.", thousands_sep + decimal_sep))
203222
return result

0 commit comments

Comments
 (0)