views:

71

answers:

3

What is the best way of determining if a given float(or double) has no significant decimal places.

f(234.0)  = true
f(34.45)  = false
f(3.1322) = false

i.e. equivalent of

EQ(((int)number) * 1.0 , number)

where EQ is a given method to compare floating points and it is OK to assume that the float fits in an integer.

+1  A: 

Round the value to the nearest integer, and calculate the absolute difference to the actual value.

If that difference is less than a certain percentage of the actual value you are close "enough".

Thorbjørn Ravn Andersen
Hi Thor, I was hoping for a solution which avoids the cast. Could some jugglery be done with Float.floatToRawIntBits() etc. which is more efficient than this?
baskin
Why? Have you profiled yet?
Thorbjørn Ravn Andersen
'MicroBenchmarking' is difficult, isn't it? And I thought regular profilers would be useless here(?)
baskin
If you cannot measure it, don't do it. Readability is more important.
Thorbjørn Ravn Andersen
A: 

You could try something like this:

public static boolean f(double d) {
    return d % 1 == 0;
}
Andrei Fierbinteanu
+1  A: 

Math.rint(x) == x

Math.rint() returns a double, so it also works for large numbers where the long result of Math.round() overflows.

Note that this also gives true for positive and negative infinity. You can explicitly exclude them by Math.rint(x) == x && !Double.isInfinite(x).

starblue
+1 for using `rint` rather than any other method of rounding to integer. Since this rounds to the *nearest* integer, it doesn't generally require an FPU rounding mode change (which can be surprisingly slow). [Though I believe that this is less of an issue these days, thanks to the SSE instructions in newer x86/x64 processors.]
Mark Dickinson