Test if a floating point number is an integer

前端 未结 12 2404
醉酒成梦
醉酒成梦 2021-02-18 22:21

This code works (C# 3)

double d;
if(d == (double)(int)d) ...;
  1. Is there a better way to do this?
  2. For extraneous reasons I want to
相关标签:
12条回答
  • 2021-02-18 22:50

    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.

    0 讨论(0)
  • 2021-02-18 22:51

    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
    
    0 讨论(0)
  • 2021-02-18 22:52

    Something like this

    double d = 4.0;
    int i = 4;
    
    bool equal = d.CompareTo(i) == 0; // true
    
    0 讨论(0)
  • 2021-02-18 22:56

    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.

    0 讨论(0)
  • 2021-02-18 22:56

    Use Math.Truncate()

    0 讨论(0)
  • 2021-02-18 22:57

    This would work I think:

    if (d % 1 == 0) {
      //...
    }
    
    0 讨论(0)
提交回复
热议问题