This cheatsheet lists every SI prefix with its symbol and multiplier, the IEC binary prefixes used for memory and file sizes, and the rules for writing them. It is for developers who format units, convert storage sizes or read sensor and electronics values. The confusion it clears up is that kilo means exactly 1000 in SI, while 1024 is called kibi. The two meanings are why a "1 TB" drive shows up as 931 GB in many tools.
The BIPM lists these 24 prefixes. Ronna, quetta, ronto and quecto were added by the CGPM in 2022, which extended the range to 10^30.
| Prefix | Symbol | Factor | Power of ten |
|---|---|---|---|
| quetta | Q | 1 000 000 000 000 000 000 000 000 000 000 | 10^30 |
| ronna | R | 1 000 000 000 000 000 000 000 000 000 | 10^27 |
| yotta | Y | 1 000 000 000 000 000 000 000 000 | 10^24 |
| zetta | Z | 1 000 000 000 000 000 000 000 | 10^21 |
| exa | E | 1 000 000 000 000 000 000 | 10^18 |
| peta | P | 1 000 000 000 000 000 | 10^15 |
| tera | T | 1 000 000 000 000 | 10^12 |
| giga | G | 1 000 000 000 | 10^9 |
| mega | M | 1 000 000 | 10^6 |
| kilo | k | 1 000 | 10^3 |
| hecto | h | 100 | 10^2 |
| deca | da | 10 | 10^1 |
| deci | d | 0.1 | 10^-1 |
| centi | c | 0.01 | 10^-2 |
| milli | m | 0.001 | 10^-3 |
| micro | µ | 0.000 001 | 10^-6 |
| nano | n | 0.000 000 001 | 10^-9 |
| pico | p | 0.000 000 000 001 | 10^-12 |
| femto | f | 0.000 000 000 000 001 | 10^-15 |
| atto | a | 0.000 000 000 000 000 001 | 10^-18 |
| zepto | z | 10^-21 | 10^-21 |
| yocto | y | 10^-24 | 10^-24 |
| ronto | r | 10^-27 | 10^-27 |
| quecto | q | 10^-30 | 10^-30 |
The IEC approved these names and symbols in December 1998 for data processing and data transmission. They are not part of the SI. Each name keeps the first two letters of the SI prefix and adds "bi".
| Prefix | Symbol | Exact value | Bytes in 1 unit |
|---|---|---|---|
| kibi | Ki | 2^10 | 1 024 |
| mebi | Mi | 2^20 | 1 048 576 |
| gibi | Gi | 2^30 | 1 073 741 824 |
| tebi | Ti | 2^40 | 1 099 511 627 776 |
| pebi | Pi | 2^50 | 1 125 899 906 842 624 |
| exbi | Ei | 2^60 | 1 152 921 504 606 846 976 |
The gap grows by roughly 2.5 percentage points for each step up, because each binary step is 1024 and each decimal step is 1000.
| Pair | Binary is bigger by |
|---|---|
| kilo and kibi | 2.40% |
| mega and mebi | 4.86% |
| giga and gibi | 7.37% |
| tera and tebi | 9.95% |
| peta and pebi | 12.59% |
| exa and exbi | 15.29% |
These come from the NIST guide to SI usage. Case matters because many symbols differ only by case, such as M for mega and m for milli.
| Rule | Right | Wrong |
|---|---|---|
| Multiples use uppercase symbols, except k, h and da | `MB`, `GHz`, `kHz` | `mB` for megabyte, `KHz` |
| Submultiples use lowercase symbols | `mm`, `ms`, `nF` | `Ms` for millisecond |
| No compound prefixes | `1 mg` | `1 µkg` |
| Prefix goes on the gram, not the kilogram | `mg`, `µg` | `mkg` |
| Symbols have no plural s | `5 km` | `5 kms` |
| One prefix per unit, no space between them | `kW` | `k W` |
| Byte is `B`, bit is `bit` (or `b` by convention) | `8 bit = 1 B` | `1 b = 1 B` |
tb = 10**12
print(round(tb / 2**30, 2), 'GiB')
print(round(500e9 / 2**30, 2), 'GiB')
931.32 GiB
465.66 GiB
A drive sold as 1 TB holds 10^12 bytes. Software that divides by 1024 per step reports that as 931.32 GiB, or 0.9095 TiB. Nothing is missing from the drive.
def fmt(x, binary=False):
if binary:
for i, s in reversed(list(enumerate(['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei']))):
if x >= 1024 ** i:
return f'{x / 1024 ** i:.2f} {s}B'
for e, s in [(18, 'E'), (15, 'P'), (12, 'T'), (9, 'G'), (6, 'M'), (3, 'k')]:
if x >= 10 ** e:
return f'{x / 10 ** e:.2f} {s}B'
return f'{x} B'
print(fmt(1536000), '|', fmt(1536000, True))
print(fmt(10**12), '|', fmt(10**12, True))
1.54 MB | 1.46 MiB
1.00 TB | 931.32 GiB
Pick one system per screen and label it. The same byte count gives different numbers, and the suffix tells the reader which one you used.
const f = (n, o) => new Intl.NumberFormat('en', o).format(n);
console.log(f(1500, { notation: 'compact' }), f(2.5e6, { notation: 'compact' }), f(3e9, { notation: 'compact' }), f(4e12, { notation: 'compact' }));
console.log(f(1536, { style: 'unit', unit: 'kilobyte' }), f(2, { style: 'unit', unit: 'gigabyte' }));
console.log(f(1500, { notation: 'compact', compactDisplay: 'long' }));
1.5K 2.5M 3B 4T
1,536 kB 2 GB
1.5 thousand
Compact notation is for readable counts, not SI. It prints B for billion where SI says G, and uppercase K for thousand where SI says k. The unit: 'kilobyte' style uses decimal kB and does not divide by 1024.
print(1e9 / 8 / 1e6, 'MB/s for 1 Gbps')
print(8e9 / 100e6, 'seconds for 1 GB at 100 Mbps')
125.0 MB/s for 1 Gbps
80.0 seconds for 1 GB at 100 Mbps
Link speeds use decimal bits per second, and file sizes use bytes. Divide the bit rate by 8 to get bytes per second, and expect less in practice because of protocol overhead.
import unicodedata
a, b = 'µ', 'μ'
print(hex(ord(a)), unicodedata.name(a))
print(hex(ord(b)), unicodedata.name(b))
print(a == b, unicodedata.normalize('NFKC', a) == b)
0xb5 MICRO SIGN
0x3bc GREEK SMALL LETTER MU
False True
The two characters look identical but compare unequal. Normalize with NFKC before comparing user input such as 5 µm.
mB means millibyte and Mb means megabit. The case carries the meaning, and a bandwidth label with Mb instead of MB is off by a factor of 8.k. Uppercase K is the kelvin, so 100 K is a temperature, and KB is not an SI spelling of kilobyte.bytes / 1024 3 yields gibibytes. Print GiB, or divide by 10 9 and print GB.µkg or kMW is not valid. The kilogram is the one SI base unit with a prefix in its name, so prefixes attach to the gram: mg, not µkg.0.1 + 0.2 prints 0.30000000000000004 in JavaScript. When converting between milli, micro and nano values, round for display and keep integers, such as microseconds, for storage.500 MB checked against a value in MiB is off by 4.86%. Convert both sides to bytes before comparing.