Skip to content

Fix fractional() emitting degenerate output when the fraction rounds to a whole#354

Open
semx wants to merge 1 commit into
python-humanize:mainfrom
semx:fix-fractional-whole-rounding
Open

Fix fractional() emitting degenerate output when the fraction rounds to a whole#354
semx wants to merge 1 commit into
python-humanize:mainfrom
semx:fix-fractional-whole-rounding

Conversation

@semx

@semx semx commented Jul 20, 2026

Copy link
Copy Markdown

Noticed while probing edge cases: fractional() emits degenerate output when the fractional part rounds to a whole number.

>>> import humanize
>>> humanize.fractional(2.9999999)
'2 1/1'        # expected '3'
>>> humanize.fractional(0.9999999)
'1/1'          # expected '1'
>>> humanize.fractional(0)
'0/1'          # expected '0'

Cause

After frac = Fraction(number - whole_number).limit_denominator(1000), when the fractional part reduces to a whole number the denominator is 1 (numerator ∈ {-1, 0, 1}). The existing special case only handled numerator == 0 (a plain integer input like 1.0), so:

  • numerator == 1 (the fraction rounded up to 1/1) fell through to the mixed-fraction branch → "2 1/1";
  • fractional(0) produced "0/1".

Changes proposed in this pull request:

  • Fold any whole-valued fractional part (denominator == 1) into the integer part, so the result reads as a normal integer.
  • Add regression tests for 0, 0.0, 2.9999999, 0.9999999, -2.9999999.

All existing tests pass (705 passed); ruff and black clean.

…to a whole

When limit_denominator(1000) reduces the fractional part to a whole number
(denominator == 1), fold it into the integer part instead of printing a
degenerate "N/1". For example fractional(2.9999999) returned "2 1/1"
instead of "3", fractional(0.9999999) returned "1/1" instead of "1",
and fractional(0) returned "0/1" instead of "0".
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.

1 participant