Skip to content

Commit f6c7cb6

Browse files
committed
Return built-in ints exactly from fractional
float() rounds integers beyond 2**53, so fractional(2**53 + 1) lost the low bit.
1 parent 8037a55 commit f6c7cb6

2 files changed

Lines changed: 7 additions & 0 deletions

File tree

‎src/humanize/number.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ def fractional(value: NumberOrString) -> str:
395395
"""
396396
import math
397397

398+
if isinstance(value, int) and not isinstance(value, bool):
399+
# An integer has no fractional part, and float() would silently round
400+
# one beyond 2**53 (e.g. 2**53 + 1), so return it exactly.
401+
return str(value)
402+
398403
try:
399404
number = float(value)
400405
if not math.isfinite(number):

‎tests/test_number.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ def test_apnumber(test_input: int | str, expected: str) -> None:
254254
(-(10**400), "-1" + "0" * 400),
255255
# Still genuinely infinite, because this is not an integer.
256256
("1e400", "+Inf"),
257+
(2**53 + 1, "9007199254740993"),
258+
(-(2**53 + 1), "-9007199254740993"),
257259
],
258260
)
259261
def test_fractional(test_input: float | str, expected: str) -> None:

0 commit comments

Comments
 (0)