Are there any drawbacks to this code, which appears to be a faster (and correct) version of java.lang.Math.round
?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
It takes advantage of the fact that, in Java, truncating to long rounds in to zero.
There are some special cases which the built in method handles, which your code does not handle. From the documentation:
NaN
, the result is 0.Integer.MIN_VALUE
, the result is equal to the value of Integer.MIN_VALUE
.Integer.MAX_VALUE
, the result is equal to the value of Integer.MAX_VALUE
.I've been testing this, and there is one key potential drawback which has not yet been described here: You are changing the rounding tie-breaking method.
Math.round()
implements the "round half up" rule, whereas your round()
method implements the "round half away from zero" rule.
For example:
Math.round(-0.5d)
=> 0L
Your.round(-0.5d)
=> -1L
This may or may not be a problem for you, but you should understand that the above method is not a drop-in replacement for Math.round()
, even after the NaN and infinity considerations already outlined.
Another relevant question: Rounding negative numbers in Java
As for the performance, there is no doubt that the above method is significantly faster than Math.round()
- it runs in about 35% of the time for randomly generated positive and negative values. This can be a worthwhile optimisation when calling this method in a tight loop. It's even better (25% of the runtime) when given only positive values, possibly because of the CPU using branch prediction.
Math.round()
is ultimately implemented by a native JNI call, which might be the cause of the performance difference. This Sun/Oracle bug suggests there might be pure-Java version in j6u22, but I can't see where, and indeed Math.round()
in j6u23 performs similarly to j6u16 in my tests. I have not tested on other versions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With