Skip to content
Python module for representing file sizes with different prefix notations
Branch: master
Clone or download
Pull request Compare This branch is 96 commits behind tbielawa:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



bitmath simplifies many facets of interacting with file sizes in various units. Functionality includes:

  • Converting between SI and NIST prefix units (kB to GiB)
  • Converting between units of the same type (SI to SI, or NIST to NIST)
  • Automatic human-readable prefix selection (like in hurry.filesize)
  • Basic arithmetic operations (subtracting 42KiB from 50GiB)
  • Rich comparison operations (1024 Bytes == 1KiB)
  • bitwise operations (<<, >>, &, |, ^)
  • argparse integration
  • progressbar integration
  • String parsing
  • Sorting

In addition to the conversion and math operations, bitmath provides human readable representations of values which are suitable for use in interactive shells as well as larger scripts and applications. The format produced for these representations is customizable via the functionality included in stdlibs string.format.

In discussion we will refer to the NIST units primarily. I.e., instead of "megabyte" we will refer to "mebibyte". The former is 10^3 = 1,000,000 bytes, whereas the second is 2^20 = 1,048,576 bytes. When you see file sizes or transfer rates in your web browser, most of the time what you're really seeing are the base-2 sizes/rates.

Don't Forget! The source for bitmath is available on GitHub.

OH! And did we mention it has 180+ unittests? Check them out for yourself.


The easiest way to install bitmath is via yum if you're on a Fedora/RHEL based distribution. bitmath is available in the main Fedora repositories, as well as the EPEL6 and EPEL7 repositories.

$ sudo yum install python-bitmath

You could also install bitmath from PyPi if you like:

$ sudo pip install bitmath

Or, if you want to install from source:

$ sudo python ./ install

If you want the bitmath manpage installed as well:

$ sudo make install


The main documentation lives at

Topics include:

  • The bitmath Module
    • Utility Functions
    • Context Managers
    • Module Variables
    • argparse integration
    • progressbar integration
  • The bitmath command-line Tool
  • Classes
    • Initializing
    • Available Classes
    • Class Methods
  • Instances
    • Instance Attributes
    • Instance Methods
    • Instance Properties
    • The Formatting Mini-Language
  • Getting Started
    • Tables of Supported Operations
    • Basic Math
    • Unit Conversion
    • Rich Comparison
    • Sorting
  • Real Life Examples
    • Download Speeds
    • Calculating how many files fit on a device
    • Printing Human-Readable File Sizes in Python
    • Calculating Linux BDP and TCP Window Scaling
  • Contributing to bitmath
  • Appendices
    • Rules for Math
    • On Units
  • NEWS
  • Copyright



>>> import bitmath
>>> log_size = bitmath.kB(137.4)
>>> log_zipped_size = bitmath.Byte(987)
>>> print "Compression saved %s space" % (log_size - log_zipped_size)
Compression saved 136.413kB space
>>> thumb_drive = bitmath.GiB(12)
>>> song_size = bitmath.MiB(5)
>>> songs_per_drive = thumb_drive / song_size
>>> print songs_per_drive

Convert Units

>>> from bitmath import *
>>> dvd_size = GiB(4.7)
>>> print "DVD Size in MiB: %s" % dvd_size.to_MiB()
DVD Size in MiB: 4812.8 MiB

Select a human-readable unit

>>> small_number = kB(100)
>>> ugly_number = small_number.to_TiB()

>>> print ugly_number
9.09494701773e-08 TiB
>>> print ugly_number.best_prefix()
97.65625 KiB

Rich Comparison

>>> cd_size = MiB(700)
>>> cd_size > dvd_size
>>> cd_size < dvd_size
>>> MiB(1) == KiB(1024)
>>> MiB(1) <= KiB(1024)


>>> sizes = [KiB(7337.0), KiB(1441.0), KiB(2126.0), KiB(2178.0),
                  KiB(2326.0), KiB(4003.0), KiB(48.0), KiB(1770.0),
                  KiB(7892.0), KiB(4190.0)]

>>> print sorted(sizes)
[KiB(48.0), KiB(1441.0), KiB(1770.0), KiB(2126.0), KiB(2178.0),
KiB(2326.0), KiB(4003.0), KiB(4190.0), KiB(7337.0), KiB(7892.0)]

Custom Formatting

  • Use of the custom formatting system
  • All of the available instance properties


>>> longer_format = """Formatting attributes for %s
   ...: This instances prefix unit is {unit}, which is a {system} type unit
   ...: The unit value is {value}
   ...: This value can be truncated to just 1 digit of precision: {value:.1f}
   ...: In binary this looks like: {binary}
   ...: The prefix unit is derived from a base of {base}
   ...: Which is raised to the power {power}
   ...: There are {bytes} bytes in this instance
   ...: The instance is {bits} bits large
   ...: bytes/bits without trailing decimals: {bytes:.0f}/{bits:.0f}""" % str(ugly_number)

>>> print ugly_number.format(longer_format)
Formatting attributes for 5.96046447754 MiB
This instances prefix unit is MiB, which is a NIST type unit
The unit value is 5.96046447754
This value can be truncated to just 1 digit of precision: 6.0
In binary this looks like: 0b10111110101111000010000000
The prefix unit is derived from a base of 2
Which is raised to the power 20
There are 6250000.0 bytes in this instance
The instance is 50000000.0 bits large
bytes/bits without trailing decimals: 6250000/50000000

Utility Functions


>>> print bitmath.getsize('python-bitmath.spec')
3.7060546875 KiB


>>> import bitmath
>>> a_dvd = bitmath.parse_string("4.7 GiB")
>>> print type(a_dvd)
<class 'bitmath.GiB'>
>>> print a_dvd
4.7 GiB


>>> for i in bitmath.listdir('./tests/', followlinks=True, relpath=True, bestprefix=True):
...     print i
('tests/', KiB(9.2900390625))
('tests/', KiB(7.1767578125))
('tests/', KiB(1.974609375))
('tests/', KiB(2.6376953125))
('tests/', KiB(3.7744140625))
('tests/', KiB(5.2568359375))
('tests/', KiB(2.03125))
('tests/', KiB(3.4580078125))
('tests/', KiB(2.2001953125))
('tests/', KiB(2.1044921875))
('tests/', KiB(3.9423828125))
('tests/', KiB(5.431640625))
('tests/', Byte(311.0))
('tests/.coverage', KiB(3.1708984375))
('tests/', KiB(5.34375))
('tests/', KiB(1.798828125))
('tests/', KiB(8.0185546875))
('tests/', KiB(4.2197265625))
('tests/listdir_symlinks/10_byte_file_link', Byte(10.0))
('tests/listdir_symlinks/depth1/depth2/10_byte_file', Byte(10.0))
('tests/listdir_nosymlinks/depth1/depth2/10_byte_file', Byte(10.0))
('tests/listdir_nosymlinks/depth1/depth2/1024_byte_file', KiB(1.0))
('tests/file_sizes/kbytes.test', KiB(1.0))
('tests/file_sizes/bytes.test', Byte(38.0))
('tests/listdir/10_byte_file', Byte(10.0))


>>> with bitmath.format(fmt_str="[{value:.3f}@{unit}]"):
...     for i in bitmath.listdir('./tests/', followlinks=True, relpath=True, bestprefix=True):
...         print i[1]

argparse Integration

Example script using bitmath.integrations.BitmathType as an argparser argument type:

import argparse
import bitmath
parser = argparse.ArgumentParser(
    description="Arg parser with a bitmath type argument")

results = parser.parse_args()
print "Parsed in: {PARSED}; Which looks like {TOKIB} as a Kibibit".format(

If ran as a script the results would be similar to this:

$ python ./ --block-size 100MiB
Parsed in: 100.0 MiB; Which looks like 819200.0 Kib as a Kibibit

progressbar Integration

Use bitmath.integrations.BitmathFileTransferSpeed as a progressbar file transfer speed widget to monitor download speeds:

import requests
import progressbar
import bitmath
import bitmath.integrations

FETCH = ''
widgets = ['Bitmath Progress Bar Demo: ', ' ',
           progressbar.Bar(marker=progressbar.RotatingMarker()), ' ',

r = requests.get(FETCH, stream=True)
size = bitmath.Byte(int(r.headers['Content-Length']))
pbar = progressbar.ProgressBar(widgets=widgets, maxval=int(size),
chunk_size = 2048
with open('/dev/null', 'wb') as fd:
    for chunk in r.iter_content(chunk_size):
        if (pbar.currval + chunk_size) < pbar.maxval:
            pbar.update(pbar.currval + chunk_size)

If ran as a script the results would be similar to this:

$ python ./
Bitmath Progress Bar Demo:  ||||||||||||||||||||||||||||||||||||||||| 1.58 MiB/s
You can’t perform that action at this time.