From cac03c80455045e0762df14a6ab08b33e6d4c9af Mon Sep 17 00:00:00 2001 From: Zhuyuyangyy <193758752+Zhuyuyangyy@users.noreply.github.com> Date: Sat, 31 Oct 2026 13:44:40 +0800 Subject: [PATCH] fix: format exact zero as a whole number in fractional --- docs/usage.md | 3 +++ src/human_readable/numbers.py | 4 ++++ tests/unit/test_numbers.py | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 83f2165..9d8704a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -344,6 +344,9 @@ human_readable.fractional(1.5) human_readable.fractional(0.3) "3/10" + +human_readable.fractional(0.0) +"0" ``` ### Scientific notation diff --git a/src/human_readable/numbers.py b/src/human_readable/numbers.py index c753b1d..2d25b67 100644 --- a/src/human_readable/numbers.py +++ b/src/human_readable/numbers.py @@ -191,6 +191,8 @@ def fractional(value: str | float) -> str: '1/3' >>> fractional(1) '1' + >>> fractional(0.0) + '0' This will always return a string. @@ -202,6 +204,8 @@ def fractional(value: str | float) -> str: """ number = float(value) + if number == 0: + return "0" whole_number = int(number) frac = fractions.Fraction(number - whole_number).limit_denominator(1000) numerator = frac.numerator diff --git a/tests/unit/test_numbers.py b/tests/unit/test_numbers.py index 0578d91..d7ab9d0 100644 --- a/tests/unit/test_numbers.py +++ b/tests/unit/test_numbers.py @@ -77,12 +77,21 @@ def test_ap_number(params: int, expected: str) -> None: [ (1, "1"), # whole number int (2.0, "2"), # whole number float + (0, "0"), # zero integer + (0.0, "0"), # zero float + (-0.0, "0"), # negative zero float + ("0", "0"), # zero string + (-2, "-2"), # negative whole number (5 / 6.0, "5/6"), # simple fraction (8.9, "8 9/10"), # compound fraction ("8.9", "8 9/10"), # string fraction + (-0.5, "-1/2"), # negative fraction + (-1.5, "-1 -1/2"), # negative compound fraction + (0.3333333, "1/3"), # limited denominator approximation + (0.0001, "0/1"), # nonzero value rounded to zero by denominator limit ], ) -def test_fractional(params: int, expected: str) -> None: +def test_fractional(params: str | float, expected: str) -> None: """Fractional number tests.""" assert numbers.fractional(params) == expected