Input Output
0 0 .0 B
999 999 .0 B
1000 1.0 kB
1023 1.0 kB
1024 1.0 kB
1601 1.6 kB
160581 160.6 kB
4066888 4.1 MB
634000000 634.0 MB
2147483647 2.1 GB
Input Output
0 0 .0 B
999 999 .0 B
1000 1000 .0 B
1023 1023 .0 B
1024 1.0 KiB
1601 1.6 KiB
160581 156.8 KiB
4066888 3.9 MiB
634000000 604.6 MiB
2147483647 2.0 GiB
Edit: Even more clarification
Some numbers have interesting rounding behaviors like the number 999950. Most code implementations would return 1000.0 kB instead of 1.0 MB. Why? Because 999950/1000 evaluates to 999.950 which is effectively rounded to 1000.0 when using String.format in Java (in most other languages too). Hench some extra checks are needed to handle cases like this.
For this challenge both styles, 1000.0 kB and 1.0 MB are accepted, although the last style is preferred.
Pseudo code / java test code:
public static String bytesToSI(long bytes){
if (bytes < 1000){
return bytes + ".0 B";
}
//Without this rounding check:
//999950 would be 1000.0 kB instead of 1.0 MB
//999950000 would be 1000.0 MB instead of 1.0 GB
int p = (int) Math.ceil(Math.log(bytes) / Math.log(1000));
if(bytes/Math.pow(1000, p) < 0.99995){
p--;
}
//Format
return String.format("%.1f %sB", bytes/Math.pow(1000, p), "kMGTPE".charAt(p-1));
}