这段代码是否有任何缺点,它似乎是一个更快(和正确)的版本java.lang.Math.round
?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
它利用了这样一个事实,即在 Java 中,将长舍入截断为零。
这段代码是否有任何缺点,它似乎是一个更快(和正确)的版本java.lang.Math.round
?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
它利用了这样一个事实,即在 Java 中,将长舍入截断为零。
内置方法可以处理一些特殊情况,而您的代码无法处理这些情况。从文档中:
NaN
,则结果为 0。Integer.MIN_VALUE
,则结果等于 的值Integer.MIN_VALUE
。Integer.MAX_VALUE
,则结果等于 的值Integer.MAX_VALUE
。我一直在对此进行测试,但这里尚未描述一个关键的潜在缺点:您正在更改舍入平局打破方法。
Math.round()
实现“四舍五入”规则,而您的round()
方法实现“远离零的半圆”规则。
例如:
Math.round(-0.5d)
=>0L
Your.round(-0.5d)
=>-1L
Math.round()
这对您来说可能是也可能不是问题,但您应该了解,即使在已经概述了 NaN 和无穷大的考虑因素之后,上述方法也不能替代.
另一个相关问题:在 Java 中舍入负数
至于性能,毫无疑问,上述方法明显快于Math.round()
- 它在大约 35% 的时间内运行随机生成的正值和负值。在紧密循环中调用此方法时,这可能是值得优化的。如果只给定正值,可能会更好(25% 的运行时间),这可能是因为 CPU 使用了分支预测。
Math.round()
最终由原生 JNI 调用实现,这可能是导致性能差异的原因。这个 Sun/Oracle 错误表明 j6u22 中可能有纯 Java 版本,但我看不出在哪里,而且Math.round()
在我的测试中,实际上 j6u23 中的性能与 j6u16 类似。我没有在其他版本上测试过。
是的; 你没有考虑下溢或上溢。务实地说,这对您的应用程序可能无关紧要。