Skip to content
Permalink
Browse files

Fix bug in StringUtils.HumanReadableByteCount.

There's an interesting story behind this, see
https://programming.guide/worlds-most-copied-so-snippet.html for the
details if you're curious. Also, I have proper attribution for the code
snippet now as well.
  • Loading branch information
LadyCailin committed Dec 11, 2019
1 parent 7f00171 commit e51603d80d27315607a540485ff3cd43ed9838e1
Showing with 20 additions and 6 deletions.
  1. +20 −6 src/main/java/com/laytonsmith/PureUtilities/Common/StringUtils.java
@@ -700,13 +700,27 @@ public static String HumanReadableByteCount(long bytes) {
* "1.0 kB" if si is true.
*/
public static String HumanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if(bytes < unit) {
return bytes + " B";
// Code copied from https://stackoverflow.com/a/3758880/731752
if(si) {
String s = bytes < 0 ? "-" : "";
long b = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
return b < 1000L ? bytes + " B"
: b < 999_950L ? String.format("%s%.1f kB", s, b / 1e3)
: (b /= 1000) < 999_950L ? String.format("%s%.1f MB", s, b / 1e3)
: (b /= 1000) < 999_950L ? String.format("%s%.1f GB", s, b / 1e3)
: (b /= 1000) < 999_950L ? String.format("%s%.1f TB", s, b / 1e3)
: (b /= 1000) < 999_950L ? String.format("%s%.1f PB", s, b / 1e3)
: String.format("%s%.1f EB", s, b / 1e6);
} else {
long b = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
return b < 1024L ? bytes + " B"
: b <= 0xfffccccccccccccL >> 40 ? String.format("%.1f KiB", bytes / 0x1p10)
: b <= 0xfffccccccccccccL >> 30 ? String.format("%.1f MiB", bytes / 0x1p20)
: b <= 0xfffccccccccccccL >> 20 ? String.format("%.1f GiB", bytes / 0x1p30)
: b <= 0xfffccccccccccccL >> 10 ? String.format("%.1f TiB", bytes / 0x1p40)
: b <= 0xfffccccccccccccL ? String.format("%.1f PiB", (bytes >> 10) / 0x1p40)
: String.format("%.1f EiB", (bytes >> 20) / 0x1p40);
}
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}

/**

0 comments on commit e51603d

Please sign in to comment.
You can’t perform that action at this time.