Skip to content

Commit 7574e0c

Browse files
gaoflowhugovk
andauthored
Carry metric() to the next SI prefix when rounding reaches 1000 (#328)
Co-authored-by: Hugo van Kemenade <[email protected]>
1 parent c2c410c commit 7574e0c

2 files changed

Lines changed: 14 additions & 2 deletions

File tree

src/humanize/number.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,14 +543,22 @@ def metric(value: float, unit: str = "", precision: int = 3) -> str:
543543
if exponent >= 33 or exponent < -30:
544544
return scientific(value, precision - 1) + unit
545545

546-
value /= 10 ** (exponent // 3 * 3)
546+
old_bucket = exponent // 3 * 3
547+
value /= 10**old_bucket
548+
digits = int(max(0, precision - exponent % 3 - 1))
549+
if exponent < 30 and round(abs(value), digits) >= 1000:
550+
exponent += 3 - exponent % 3
551+
new_bucket = exponent // 3 * 3
552+
value /= 10 ** (new_bucket - old_bucket)
553+
digits = int(max(0, precision - exponent % 3 - 1))
554+
547555
if exponent >= 3:
548556
ordinal_ = "kMGTPEZYRQ"[exponent // 3 - 1]
549557
elif exponent < 0:
550558
ordinal_ = "mμnpfazyrq"[(-exponent - 1) // 3]
551559
else:
552560
ordinal_ = ""
553-
value_ = format(value, f".{int(max(0, precision - exponent % 3 - 1))}f")
561+
value_ = format(value, f".{digits}f")
554562
if not (unit or ordinal_) or unit in ("°", "′", "″"):
555563
space = ""
556564
else:

tests/test_number.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ def test_clamp(test_args: list[typing.Any], expected: str) -> None:
257257
([1234.56], "1.23 k"),
258258
([12345, "", 6], "12.3450 k"),
259259
([200_000], "200 k"),
260+
([999.9, "V"], "1.00 kV"),
261+
([999.99, "V"], "1.00 kV"),
262+
([999_999, "V"], "1.00 MV"),
263+
([0.0009999, "V"], "1.00 mV"),
260264
([1e25, "m"], "10.0 Ym"),
261265
([1e26, "m"], "100 Ym"),
262266
([1e27, "A"], "1.00 RA"),

0 commit comments

Comments
 (0)