Most people are familiar with a few of the more common prefixes used before many units to denote a fraction or a multiple of the unit - kilograms, megabytes, centimetres etc.. As well as these there a number of less well known ones, going right up to yotta and right down to yocto.
As a simple but hopefully enlightening programming exercise I have put together this short Python program to list all the prefixes along with their corresponding powers and multipliers.
If you are the sort of person who reads programming blogs like this one you will know that using kilo, mega, giga etc. to prefix the word "byte" is technically inaccurate. Way back in 1998 an organisation called The International Electrotechnical Commission came up with a set of alternatives to apply to computer memory which is measured in powers of 2 rather than powers of 10. Instead of kilobyte/megabyte/gigabyte etc. their sequence goes kibibyte/mebibyte/gibibyte etc.. This has never caught on of course, and these proposed alternatives have languished in obscurity for the last two decades. This is presumably because the strictly innaccurate kilo/mega/giga usage already had an unstoppable inertia; it might also be because kibi, mebi and gibi just sound plain silly. Despite that I will include them in this project.
To get started create a new folder somewhere and within it create an empty file called siprefixes.py. You can download the source code as a zip or clone/download from Github if you prefer. Open the file and type or paste this code.
Source Code Links
siprefixes.py
def main(): """ Call functions to create lists of prefixes and powers in base 10 and base 2, then print them. """ print("-----------------") print("| codedrome.com |") print("| SI Prefixes |") print("-----------------\n") base10_list = create_base10_list() print_base10(base10_list) print("") base2_list = create_base2_list() print_base2(base2_list) def create_base10_list(): """ Create a list of base 10 prefixes with corresponding powers. """ base10 = [{"prefix": "yotta", "power": 24}, {"prefix": "zetta", "power": 21}, {"prefix": "exa", "power": 18}, {"prefix": "peta", "power": 15}, {"prefix": "tera", "power": 12}, {"prefix": "giga", "power": 9}, {"prefix": "mega", "power": 6}, {"prefix": "kilo", "power": 3}, {"prefix": "hecto", "power": 2}, {"prefix": "deca", "power": 1}, {"prefix": "(none)", "power": 0}, {"prefix": "deci", "power": -1}, {"prefix": "centi", "power": -2}, {"prefix": "milli", "power": -3}, {"prefix": "micro", "power": -6}, {"prefix": "nano", "power": -9}, {"prefix": "pico", "power": -12}, {"prefix": "femto", "power": -15}, {"prefix": "atto", "power": -18}, {"prefix": "zepto", "power": -21}, {"prefix": "yocto", "power": -24}] return base10 def print_base10(base10_list): """ Use list from create_base10_list function to print prefixes, powers and values. """ for b in base10_list: if b["power"] >= 0: print("{:6s} 10^{:<3} = {:>26}".format(b["prefix"], b["power"], 10**b["power"])) else: print("{:6s} 10^{:<3} = {:>26.{prec}f}".format(b["prefix"], b["power"], 10**b["power"], prec=abs(b["power"]))) def create_base2_list(): """ Create a list of base 2 prefixes with corresponding powers. """ base2 = [{"prefix": "kibibyte", "power": 10}, {"prefix": "mebibyte", "power": 20}, {"prefix": "gibibyte", "power": 30}, {"prefix": "tebibyte", "power": 40}, {"prefix": "pebibyte", "power": 50}, {"prefix": "exbibyte", "power": 60}, {"prefix": "zebibyte", "power": 70}, {"prefix": "yobibyte", "power": 80}] return base2 def print_base2(base2_list): """ Use list from create_base2_list function to print prefixes, powers and values. """ for b in base2_list: print("1 {}: 2^{} = {:>33,} bytes".format(b["prefix"], b["power"], 2**b["power"])) main()
The main function simply calls the four functions which come next.
The create_base10_list function initializes and returns a list of dictionaries, holding all the prefixe and power pairs. The next function is print_base10 which takes the list from create_base10_list and prints out the prefix, the power equation, and the multiplier.
The next two functions are create_base2_list and print_base2 which replicate the functionality of the previous functions but for the base 2 memory prefixes.
That's all there is to the code so run it with this command:
Run
python3.7 siprefixes.py
The output is
Program Output
----------------- | codedrome.com | | SI Prefixes | ----------------- yotta 10^24 = 1000000000000000000000000 zetta 10^21 = 1000000000000000000000 exa 10^18 = 1000000000000000000 peta 10^15 = 1000000000000000 tera 10^12 = 1000000000000 giga 10^9 = 1000000000 mega 10^6 = 1000000 kilo 10^3 = 1000 hecto 10^2 = 100 deca 10^1 = 10 (none) 10^0 = 1 deci 10^-1 = 0.1 centi 10^-2 = 0.01 milli 10^-3 = 0.001 micro 10^-6 = 0.000001 nano 10^-9 = 0.000000001 pico 10^-12 = 0.000000000001 femto 10^-15 = 0.000000000000001 atto 10^-18 = 0.000000000000000001 zepto 10^-21 = 0.000000000000000000001 yocto 10^-24 = 0.000000000000000000000001 1 kibibyte: 2^10 = 1,024 bytes 1 mebibyte: 2^20 = 1,048,576 bytes 1 gibibyte: 2^30 = 1,073,741,824 bytes 1 tebibyte: 2^40 = 1,099,511,627,776 bytes 1 pebibyte: 2^50 = 1,125,899,906,842,624 bytes 1 exbibyte: 2^60 = 1,152,921,504,606,846,976 bytes 1 zebibyte: 2^70 = 1,180,591,620,717,411,303,424 bytes 1 yobibyte: 2^80 = 1,208,925,819,614,629,174,706,176 bytes
The powers of 10 exhibit a very satisfying symmetry, as well as some staggering largeness and smallness at the extreme ends. The measures of memory don't take us to such extremes but are large enough for the time being. I wonder how long it will be before we can go out and buy a 1 yobibyte drive?