Skip to content

Commit 43ebe21

Browse files
committed
Fix scientific() on small positive numbers.
Checking a number is negative using `'-' in string_value` leads to confusion because 1e-30 and -1e30 both contain a '-' but only one of them is negative. This bug had found its way into the tests and the docstring. Additionally, the removal of redundant leading '0's and '+'s from the exponent would only kick in if both were present so that 1e20 would become 10⁺²⁰ instead of just 10²⁰ and the insertion of negative exponents could lead to outputs such as 3.00 x 10⁻⁺²⁰.
1 parent 7688f20 commit 43ebe21

2 files changed

Lines changed: 11 additions & 23 deletions

File tree

src/humanize/number.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ def scientific(value: NumberOrString, precision: int = 2) -> str:
337337
>>> scientific(int(500))
338338
'5.00 x 10²'
339339
>>> scientific(-1000)
340-
'1.00 x 10³'
340+
'-1.00 x 10³'
341341
>>> scientific(1000, 1)
342342
'1.0 x 10³'
343343
>>> scientific(1000, 3)
@@ -369,35 +369,19 @@ def scientific(value: NumberOrString, precision: int = 2) -> str:
369369
"7": "⁷",
370370
"8": "⁸",
371371
"9": "⁹",
372-
"+": "⁺",
373372
"-": "⁻",
374373
}
375-
negative = False
376374
try:
377-
if "-" in str(value):
378-
value = str(value).replace("-", "")
379-
negative = True
380-
381-
if isinstance(value, str):
382-
value = float(value)
383-
384-
fmt = "{:.%se}" % str(int(precision))
385-
n = fmt.format(value)
386-
375+
value = float(value)
387376
except (ValueError, TypeError):
388377
return str(value)
389-
378+
fmt = "{:.%se}" % str(int(precision))
379+
n = fmt.format(value)
390380
part1, part2 = n.split("e")
391-
if "-0" in part2:
392-
part2 = part2.replace("-0", "-")
393-
394-
if "+0" in part2:
395-
part2 = part2.replace("+0", "")
381+
# Remove redundant leading '+' or '0's (preserving the last '0' for 10⁰).
382+
part2 = re.sub(r"^\+?(\-?)0*(.+)$", r"\1\2", part2)
396383

397384
new_part2 = []
398-
if negative:
399-
new_part2.append(exponents["-"])
400-
401385
for char in part2:
402386
new_part2.append(exponents[char])
403387

tests/test_number.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def test_fractional(test_input: float | str, expected: str) -> None:
144144
"test_args, expected",
145145
[
146146
([1000], "1.00 x 10³"),
147-
([-1000], "1.00 x 10³"),
147+
([-1000], "-1.00 x 10³"),
148148
([5.5], "5.50 x 10⁰"),
149149
([5781651000], "5.78 x 10⁹"),
150150
(["1000"], "1.00 x 10³"),
@@ -156,6 +156,10 @@ def test_fractional(test_input: float | str, expected: str) -> None:
156156
([float(0.3), 1], "3.0 x 10⁻¹"),
157157
([1000, 0], "1 x 10³"),
158158
([float(0.3), 0], "3 x 10⁻¹"),
159+
([float(1e20)], "1.00 x 10²⁰"),
160+
([float(2e-20)], "2.00 x 10⁻²⁰"),
161+
([float(-3e20)], "-3.00 x 10²⁰"),
162+
([float(-4e-20)], "-4.00 x 10⁻²⁰"),
159163
],
160164
)
161165
def test_scientific(test_args: list[typing.Any], expected: str) -> None:

0 commit comments

Comments
 (0)