Skip to content

Instantly share code, notes, and snippets.

@rgkimball
Created June 17, 2021 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgkimball/d3301af7a6993c62442685a063632502 to your computer and use it in GitHub Desktop.
Save rgkimball/d3301af7a6993c62442685a063632502 to your computer and use it in GitHub Desktop.
Human-readable Size
def readable_size(byte_size: int, base: int = 10, decimals: int = 1):
"""
Given the size of an object in bytes, returns a human-readable alternative.
For ex:
>>> readable_size(44000000)
42.0 MB
Supports sizes up to 1024 yobibytes in Binary or 1000 yottabytes in Decimal SI.
Inspired by the following StackOverflow questions:
- https://stackoverflow.com/questions/1094841/get-human-readable-version-of-file-size
- https://stackoverflow.com/questions/3758606/how-can-i-convert-byte-size-into-a-human-readable-format-in-java
:param byte_size: the size of the object in bytes
:param base: optional int, either 2 for Binary or 10 for Decimal SI. Binary is the default.
:param decimals: optional int, specify the number of significant digits to return
:return: str formatted with the maximum possible units and the suffix, like '50.0 MiB'
"""
if base == 2:
unit, pre = 2 ** 10, 'kMGTPEZY'
elif base == 10:
unit, pre = 10 ** 3, 'KMGTPEZY'
else:
raise ValueError('Base must either be 10 or 2; given: {0}'.format(base))
abs_bytes = abs(byte_size)
if abs_bytes < unit:
return '{0:.1f} B'.format(byte_size)
exp = int(math.log(abs_bytes) / math.log(unit))
th = math.ceil(math.pow(unit, exp) * (unit - 0.05))
if exp < 6 and abs_bytes >= th - (51 if (th & 0xFFF) == 0xD00 else 0):
exp += 1
suffix = pre[exp - 1]
# Discard significant digits to improve floating point precision of really large values when printing
if exp > 4:
byte_size /= unit
exp -= 1
return '{0:.{3}f} {1}{2}B'.format(byte_size / math.pow(unit, exp), suffix, 'i' if base == 2 else '', decimals)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment