From 6da00669f49efbce87d7706c5bfc37c48e39e289 Mon Sep 17 00:00:00 2001 From: Jah-yee <166608075+Jah-yee@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:43:41 +0800 Subject: [PATCH] fix(intcomma): handle scientific notation for large/small floats Black formatting applied per pre-commit.ci requirements. --- src/humanize/number.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/humanize/number.py b/src/humanize/number.py index 52a5356a..d9f08f8c 100644 --- a/src/humanize/number.py +++ b/src/humanize/number.py @@ -197,7 +197,31 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str: if ndigits is not None: result = f"{value:,.{ndigits}f}" else: - result = f"{value:,}" + if isinstance(value, float) and value == int(value): + # Whole-number float: format as int to avoid trailing .0 + result = f"{int(value):,}" + elif ( + isinstance(value, float) + and value != 0 + and (abs(value) >= 1e15 or abs(value) <= 1e-5) + ): + # Python repr uses scientific notation for very large/small floats, + # which breaks the , format specifier. Use Decimal for proper formatting. + from decimal import Decimal + + d = Decimal(str(value)) + formatted = f"{d:f}" + if "." in formatted: + int_part, dec_part = formatted.split(".") + dec_part = dec_part.rstrip("0") + if dec_part: + result = f"{int(int_part):,}.{dec_part}" + else: + result = f"{int(int_part):,}" + else: + result = f"{int(formatted):,}" + else: + result = f"{value:,}" if thousands_sep != "," or decimal_sep != ".": result = result.translate(str.maketrans(",.", thousands_sep + decimal_sep)) return result