From af93d314ef7825d316ab54c3f6bda0f93977258e Mon Sep 17 00:00:00 2001 From: Mayur Dhavan <118877752+mayur-dhavan@users.noreply.github.com> Date: Mon, 26 Oct 2026 00:11:33 +0530 Subject: [PATCH 1/2] Handle metric rounding carry at the quetta boundary Remove unnecessary condition for rounding carry in number formatting. --- src/humanize/number.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/humanize/number.py b/src/humanize/number.py index 52a5356a..b1e62f18 100644 --- a/src/humanize/number.py +++ b/src/humanize/number.py @@ -578,12 +578,16 @@ def metric(value: float, unit: str = "", precision: int = 3) -> str: if exponent >= 33 or exponent < -30: return scientific(value, precision - 1) + unit + original = value old_bucket = exponent // 3 * 3 value /= 10**old_bucket digits = int(max(0, precision - exponent % 3 - 1)) # Absorb a rounding carry (9.999 -> 10.0) by bumping the exponent. - if exponent < 30 and round(abs(value), digits) >= 10 ** (exponent % 3 + 1): + if round(abs(value), digits) >= 10 ** (exponent % 3 + 1): exponent += 1 + if exponent >= 33: + # Rounded past quetta: no larger prefix exists. + return scientific(original, precision - 1) + unit new_bucket = exponent // 3 * 3 value /= 10 ** (new_bucket - old_bucket) digits = int(max(0, precision - exponent % 3 - 1)) From b32f1f6a0ba247b5ca9e083cd5d21a2e78b8d9b1 Mon Sep 17 00:00:00 2001 From: Mayur Dhavan <118877752+mayur-dhavan@users.noreply.github.com> Date: Mon, 26 Oct 2026 00:11:58 +0530 Subject: [PATCH 2/2] Add metric regression tests for the quetta rounding boundary Add test cases for rounding carry at quetta boundary. --- tests/test_number.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_number.py b/tests/test_number.py index 5fb12fa6..d940f8f1 100644 --- a/tests/test_number.py +++ b/tests/test_number.py @@ -332,6 +332,12 @@ def test_clamp(test_args: list[typing.Any], expected: str) -> None: ([1.235e29, "A"], "124 RA"), ([2.56e-30, "V"], "2.56 qV"), ([2.596e32, "F"], "260 QF"), + # Rounding carry at the quetta boundary (issue #423) + ([9.996e30], "10.0 Q"), + ([9.996e31], "100 Q"), + ([9.996e32], "1.00 x 10\u00b3\u00b3"), + ([9.999e-30], "10.0 q"), + ([-9.996e31], "-100 Q"), ([1e50], "1.00 x 10⁵⁰"), ([1e-50], "1.00 x 10⁻⁵⁰"), ([-1500, "V"], "-1.50 kV"),