此代码是否存在任何缺陷,这似乎是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中,截断为长轮到零。
答案 0 :(得分:15)
内置方法处理的内容有special cases,代码无法处理。来自文档:
NaN
,则结果为0. Integer.MIN_VALUE
的值,则结果等于Integer.MIN_VALUE
的值。Integer.MAX_VALUE
的值,结果等于Integer.MAX_VALUE
的值。答案 1 :(得分:5)
是;你没有考虑下溢或溢出。从语用上讲,这可能与您的申请无关。
答案 2 :(得分:3)
我一直在测试这个,有一个关键的潜在缺点,这里还没有描述:你正在改变rounding tie-breaking方法。
Math.round()
实现了“round half up”规则,而你的round()
方法实现了“从零开始的一半”规则。
例如:
Math.round(-0.5d)
=> 0L
Your.round(-0.5d)
=> -1L
这对您来说可能是一个问题,也可能不是问题,但是您应该理解上述方法不是Math.round()
的替代方法,即使已经概述了NaN和无穷大的考虑因素。
另一个相关问题:Rounding negative numbers in Java
至于性能,毫无疑问,上述方法明显快于Math.round()
- 它在大约35%的时间内运行,随机生成的正负值。在紧密循环中调用此方法时,这可能是一个值得优化的。当仅给出正值时,它甚至更好(运行时的25%),可能是因为CPU使用branch prediction。
Math.round()
最终由本机JNI调用实现,这可能是性能差异的原因。 This Sun/Oracle bug表明在j6u22中可能存在纯Java版本,但是我无法看到j6u23中的Math.round()
在我的测试中与j6u16类似地执行。我没有在其他版本上测试过。