我已经看到很多关于 SO 与舍入浮点值相关的讨论,但考虑到效率方面,没有可靠的问答。所以这里是:
将浮点值四舍五入到最接近的整数的最有效(但正确)方法是什么?
(int) (mFloat + 0.5);
或者
Math.round(mFloat);
或者
FloatMath.floor(mFloat + 0.5);
或者是其他东西?
最好我想使用标准 java 库中可用的东西,而不是我必须导入的一些外部库。
我已经看到很多关于 SO 与舍入浮点值相关的讨论,但考虑到效率方面,没有可靠的问答。所以这里是:
将浮点值四舍五入到最接近的整数的最有效(但正确)方法是什么?
(int) (mFloat + 0.5);
或者
Math.round(mFloat);
或者
FloatMath.floor(mFloat + 0.5);
或者是其他东西?
最好我想使用标准 java 库中可用的东西,而不是我必须导入的一些外部库。
根据我认为您所指的问答,各种方法的相对效率取决于您使用的平台。
但底线是:
Math.floor
/进行了性能修复StrictMath.floor
,并且参考:
public class Main {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
measurementIteration();
}
}
public static void measurementIteration() {
long s, t1 = 0, t2 = 0;
float mFloat = 3.3f;
int f, n1 = 0, n2 = 0;
for (int i = 0; i < 1E4; i++) {
switch ((int) (Math.random() * 2)) {
case 0:
n1 += 1E4;
s = System.currentTimeMillis();
for (int k = 0; k < 1E4; k++)
f = (int) (mFloat + 0.5);
t1 += System.currentTimeMillis() - s;
break;
case 1:
n2 += 1E4;
s = System.currentTimeMillis();
for (int k = 0; k < 1E4; k++)
f = Math.round(mFloat);
t2 += System.currentTimeMillis() - s;
break;
}
}
System.out.println(String.format("(int) (mFloat + 0.5): n1 = %d -> %.3fms/1000", n1, t1 * 1000.0 / n1));
System.out.println(String.format("Math.round(mFloat) : n2 = %d -> %.3fms/1000", n2, t2 * 1000.0 / n2));
}
}
Java SE6 上的输出:
(int) (mFloat + 0.5): n1 = 500410000 -> 0.003ms/1000
Math.round(mFloat) : n2 = 499590000 -> 0.022ms/1000
Java SE7 上的输出(感谢alex提供的结果):
(int) (mFloat + 0.5): n1 = 50120000 -> 0,002ms/1000
Math.round(mFloat) : n2 = 49880000 -> 0,002ms/1000
如您所见,Math.round
从 SE6 到 SE7 的性能有了巨大的提升。我认为在 SE7 中不再有显着差异,您应该选择对您来说更具可读性的内容。
我应该这样做,Math.round(mFloat)
因为它将舍入逻辑封装在一个方法中(即使它不是你的方法)。
根据其文档,您编写的代码与Math.round
执行的代码相同(除了检查边界情况)。
无论如何,更重要的是算法的时间复杂性,而不是类似常量的小东西的时间......除非你正在编写将被调用数百万次的东西!:D
编辑:我不知道 FloatMath。它来自JDK吗?
您可以使用System.currentTimeMillis()
. 你会发现差异太小了
简单地添加 0.5 将给出负数的错误结果。请参阅Math.round 的更快实现?以获得更好的解决方案。