diff --git a/src/human_readable/files.py b/src/human_readable/files.py index b28376b..13d1a0e 100644 --- a/src/human_readable/files.py +++ b/src/human_readable/files.py @@ -61,5 +61,10 @@ def file_size( for i, suffix in enumerate(suffixes): unit = base ** (i + 2) if byte_size < unit: - return f"{base * byte_size / unit:{formatting}}{suffix}" + formatted = f"{base * byte_size / unit:{formatting}}" + # Rounding can push the mantissa to base (e.g. 999,999 bytes is + # 999.999 KB, which rounds to "1000.0 KB"). Step up one suffix. + if float(formatted) >= base and i + 1 < len(suffixes): + return f"{byte_size / unit:{formatting}}{suffixes[i + 1]}" + return f"{formatted}{suffix}" return f"{base * byte_size / unit:{formatting}}{suffix}" diff --git a/tests/unit/test_files.py b/tests/unit/test_files.py index 4c6ee6e..b173448 100644 --- a/tests/unit/test_files.py +++ b/tests/unit/test_files.py @@ -15,6 +15,10 @@ (2900000, "2.9 MB"), # millions number (2000000000, "2.0 GB"), # billions number (10**26 * 30, "3000.0 YB"), # giant number + # Rollover: mantissa rounds up to base, must carry to the next suffix + (999999, "1.0 MB"), + (999999999, "1.0 GB"), + (999999999999, "1.0 TB"), ], ) def test_file_size(params: int, expected: str) -> None: