This code works (C# 3)
double d;
if(d == (double)(int)d) ...;
A simple test such as 'x == floor(x)' is mathematically assured to work correctly, for any fixed-precision FP number.
All legal fixed-precision FP encodings represent distinct real numbers, and so for every integer x, there is at most one fixed-precision FP encoding that matches it exactly.
Therefore, for every integer x that CAN be represented in such way, we have x == floor(x) necessarily, since floor(x) by definition returns the largest FP number y such that y <= x and y represents an integer; so floor(x) must return x.
This will let you choose what precision you're looking for, plus or minus half a tick, to account for floating point drift. The comparison is integral also which is nice.
static void Main(string[] args)
{
const int precision = 10000;
foreach (var d in new[] { 2, 2.9, 2.001, 1.999, 1.99999999, 2.00000001 })
{
if ((int) (d*precision + .5)%precision == 0)
{
Console.WriteLine("{0} is an int", d);
}
}
}
and the output is
2 is an int
1.99999999 is an int
2.00000001 is an int
Something like this
double d = 4.0;
int i = 4;
bool equal = d.CompareTo(i) == 0; // true
If your double is the result of another calculation, you probably want something like:
d == Math.Floor(d + 0.00001);
That way, if there's been a slight rounding error, it'll still match.
Use Math.Truncate()
This would work I think:
if (d % 1 == 0) {
//...
}