Java: Formatting byte size to human readable format

The code in the first version of this article was flawed. The code below is now the recommended solution. See the following article for details:

The most copied StackOverflow snippet of all time is flawed!

SI (1 k = 1,000)

public static String humanReadableByteCountSI(long bytes) {
    if (-1000 < bytes && bytes < 1000) {
        return bytes + " B";
    }
    CharacterIterator ci = new StringCharacterIterator("kMGTPE");
    while (bytes <= -999_950 || bytes >= 999_950) {
        bytes /= 1000;
        ci.next();
    }
    return String.format("%.1f %cB", bytes / 1000.0, ci.current());
}

Binary (1 K = 1,024)

public static String humanReadableByteCountBin(long bytes) {
    long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
    if (absB < 1024) {
        return bytes + " B";
    }
    long value = absB;
    CharacterIterator ci = new StringCharacterIterator("KMGTPE");
    for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
        value >>= 10;
        ci.next();
    }
    value *= Long.signum(bytes);
    return String.format("%.1f %ciB", value / 1024.0, ci.current());
}

Examples

Input SI
1k = 1000
Binary
1k = 1024
0 0 B 0 B
27 27 B 27 B
999 999 B 999 B
1000 1.0 kB 1000 B
1023 1.0 kB 1023 B
1024 1.0 kB 1.0 KiB
1728 1.7 kB 1.7 KiB
1855425871872 1.9 TB 1.7 TiB
Long.MAX_VALUE 9.2 EB 8.0 EiB

Comments (6)

User avatar

These are the international standard symbols used for describing the values you calculate. You should use them and not strings like GiB

  • kB, kilo
  • MB, mega
  • GB, giga
  • TB, tera
  • PB, peta
  • EB, exa
  • ZB zetta
  • YB, yotta
by Doug Blake |  Reply
User avatar

GB and GiB are two different notations. G is the SI variant and stands, as you say, for giga (10003). Gi is the IEC standard and stands for gibi (10243).

But I agree, if I were to pick one, I'd go with the SI standard.

by Andreas Lundblad |  Reply
User avatar

For the binary can't you use the shift operator ? like b < 1<<10 ? String.format("%.1f KiB", bytes>>10)

by Pino |  Reply
User avatar

Unfortunately no. The unit should for example go from KiB to MiB as soon as the number of bytes is closer to 10243 than it is to 1023.9×10242. This happens between these two values.

by Andreas Lundblad |  Reply
User avatar

Why use 0xfffccccccccccccL?

by Ma |  Reply
User avatar

Because that is the point at which one should transition from PB to EB. Think of it like this: 0xfffccccccccccccL is to 250 what 999,950,000 is to 109.

by Andreas Lundblad |  Reply

Add comment