将浮点值舍入到java中最接近的整数的最有效方法是什么?
我已经看到很多有关舍入浮动值的SO的讨论,但考虑到效率方面没有可靠的问答。 所以这里是:
将浮点值舍入到最接近的整数的最有效(但正确)方法是什么?
(int) (mFloat + 0.5);
要么
Math.round(mFloat);
要么
FloatMath.floor(mFloat + 0.5);
或者是其他东西?
我最好使用标准java库中可用的东西,而不是我必须导入的一些外部库。
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
正如您所看到的,从SE6到SE7, Math.round
性能有了很大的提升。 我认为在SE7中不再存在显着差异,你应该选择对你来说更具可读性的东西。
基于我认为您所指的Q&A,各种方法的相对效率取决于您使用的平台 。
但最重要的是:
- 最新的JRE具有
Math.floor
/StrictMath.floor
的性能修复,以及 - 除非你做了很多的四舍五入,否则你可能没有任何区别。
参考文献:
- 这是否意味着Java Math.floor非常慢?
- http://bugs.sun.com/view_bug.do?bug_id=6908131(“java.lang.StrictMath.floor(double)&java.lang.StrictMath.ceil(double )的纯Java实现”)
我应该去Math.round(mFloat)
因为它在方法中封装了舍入逻辑(即使它不是你的方法)。
根据其文档 ,您编写的代码与Math.round
执行的代码相同(除了检查边界情况)。
无论如何,更重要的是你的算法的时间复杂性,而不是那些小的类似常量的东西…除了你编程的东西将被调用数百万次! :d
编辑:我不知道FloatMath。 它来自JDK吗?
您可以使用System.currentTimeMillis()
对其进行基准测试。 你会发现差异太小了
简单地添加0.5将给出负数的错误结果。 请参阅更快的Math.round实现? 为了更好的解决方案。