Skip to content

Fix intcomma() digit loss on large decimal strings - #506

Open
ekanshul wants to merge 1 commit into
python-humanize:mainfrom
ekanshul:fix-intcomma-large-decimal-string
Open

ekanshul wants to merge 1 commit into
python-humanize:mainfrom
ekanshul:fix-intcomma-large-decimal-string

Conversation

@ekanshul

@ekanshul ekanshul commented Nov 5, 2026

Copy link
Copy Markdown

Fixes #496

intcomma('1234567890123456.78') returned '1,234,567,890,123,456.8' — the last digit of the fraction was lost because the string branch converted via float(), which can't represent 16-digit integers with paise precisely. A Decimal input already worked correctly.

Fix: for decimal strings, keep the original digit string for the ndigits=None path (group the integer part, keep the fraction verbatim) and convert through Decimal when ndigits is specified so explicit rounding still works without float rounding.

Added parametrized cases in tests/test_number.py for both branches.

Verified locally: tests/test_number.py — 243 passed.

Co-authored-by: CommandCodeBot noreply@commandcode.ai

Fixes python-humanize#496

intcomma() converted decimal strings with float(value), losing precision
on large values (e.g. '1234567890123456.78' -> '...456.8').
Keep the exact string for the ndigits=None path and use Decimal when
ndigits is given, preserving all input digits.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

@Ekko82 Ekko82 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared the public humanize.intcomma API on base d16e6352 and head 25087f91 with CPython 3.13.9 on Windows, after reading the complete two-file diff. The large-decimal cases pass on head; the inline note covers two exponent-string regressions.

Validation covered eight behavior cases per ref with normal package imports. The full suite and translated locales were not run. Current Actions runs report action_required.

Comment thread src/humanize/number.py
result = f"{value:,}"
if is_str_decimal:
# Format the original digit string directly so no precision is lost.
int_part, _, frac_part = value.partition(".")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep formatting exponent strings with a decimal point

frac_part also contains any exponent suffix. With ndigits=None, intcomma('1.2e3') now returns '1.2e3' instead of the base result '1,200.0'; intcomma('1.2e-3') likewise changes from '0.0012' to '1.2e-3'. These inputs still format correctly when ndigits is explicit because that path uses Decimal. Please preserve exponent normalization in this branch and include these two cases alongside the new precision tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

intcomma() loses digits from large decimal strings

2 participants