挑战与起源
在Stack Overflow上,一个流行的问题是:如何在Java中将字节大小转换为人类可读的格式?投票最多的答案有一个很好的方法可以做到这一点,但这是代码高尔夫,我们可以做得更好,不是吗?
您面临的挑战是编写一种方法或程序,该方法或程序可以将给定字节数转换为正确的人类可读格式,并使用您的语言将结果打印为标准格式。*
*请参阅规则以进行进一步说明!
输入值
输入将始终为正数字节,最大(2 ^ 31)-1。
输出量
您可以选择是否使用国际单位制或二进制表示法作为输出(SI表示法可能为您节省一些字节)。
SI: B, kB, MB, GB
Binary: B, KiB, MiB, GiB
注意:由于输入范围的限制,无法使用高于GB或GiB的单位。
输出示例
国际单位制:
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
规则
- 不允许用于字节格式化的内置函数!
- 输出应始终采用相同的注释标准,不得混用SI或二进制;
- 输出应始终以可能的最大单位为单位,其中结果数仍大于或等于1;
- 输出应始终有一个十进制数,但是当结果输出以字节(B)为单位时,您可以选择打印一个整数。
- 您可以选择是否要在数字和单位之间添加空格,制表符或不添加任何内容。
- 通过STDIN或功能参数接收输入;
- 输出被打印到控制台或作为字符串(或类似的字符容器)返回;
- 这是代码高尔夫球,因此最短的答案为胜。玩得开心!
编辑:更加澄清
一些数字具有有趣的舍入行为,例如数字999950。大多数代码实现将返回1000.0 kB而不是1.0 MB。为什么?因为999950/1000的计算结果为999.950,所以在Java中使用String.format时(实际上在大多数其他语言中),有效地舍入为1000.0。需要处理一些额外的检查来处理这样的情况。
对于此挑战,尽管首选最后一种样式,但都接受1000.0 kB和1.0 MB这两种样式。
伪代码/ java测试代码:
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)); }
999999
和1000000
?160581
展示四舍五入,应该是1000.0kB
和1.0MB
吗?
kB
(请注意小写k)