To check if the value is NaN
,
we can use Double.isNaN()
.
in grepcode,
implementation is like this.
public static boolean isNaN(double v){
return (v != v);
}
Double.isInfinite()
is like this.
public static boolean isInfinite(double v){
return (v == Double.POSITIVE_INFINITY) || (v == Double.NEGATIVE_INFINITY);
}
However, Double.isFinite()
is like this.
public static boolean isFinite(double v){
return Math.abs(v) <= Double.MAX_VALUE;
}
So my first question is,
Why not simply returns !( Double.isNaN(v) || Double.isInfinite(v) )
?
Are there any performance reasons?
I think A is faster than B. Is this wrong?
A. one !=
, two ==
s, two ||
s, and one !
B. abs()
and <=
My second question is,
" is this completely identical ?"
that is,
" does this method return true
? "
public static boolean test(){
long x = Long.MIN_VALUE;
for(;;){ //iterate from Long.MIN_VALUE to Long.MAX_VALUE
double d = Double.longBitsToDouble(x);
boolean a = ! ( Double.isNaN(d) || Double.isInfinite(d) );
boolean b = Double.isFinite(d);
if(a != b) return false;
if(x == Long.MAX_VALUE) break;
x++;
}
return true;
}
Math.abs(double) is faster than it appears
return (a <= 0.0D) ? 0.0D - a : a;
as the methods is recognised as an intrinsic in HotSpot and many other JVMs. An intrinsic is replaced by code which does the same thing, but more efficiently.
See vmSymbols.hpp for a list of symbols which are replaced by hand coded machine code.
so, believing GrepCode is sometimes dangerous.
GrepCode tells you what the source looks like. It is hard to second guess what optimisations will be performed on Java code when it is converted to native code. The JIT has clever optimisations, dead code elimination which can make optimisation which look faster/smarter run slower.
If in doubt, stick to the simplest code, and it is likely the JIT has a special optimisation for it. Try something tricky and you might find, the JIT doesn't have an optimisation for it and it will be slower.