[c#] How to determine if a decimal/double is an integer?

How do I tell if a decimal or double value is an integer?

For example:

decimal d = 5.0; // Would be true
decimal f = 5.5; // Would be false

or

double d = 5.0; // Would be true
double f = 5.5; // Would be false

The reason I would like to know this is so that I can determine programmatically if I want to output the value using .ToString("N0") or .ToString("N2"). If there is no decimal point value, then I don't want to show that.

This question is related to c#

The answer is


    public static bool isInteger(decimal n)
    {
        return n - (Int64)n == 0;
    }

How about this?

public static bool IsInteger(double number) {
    return number == Math.Truncate(number);
}

Same code for decimal.

Mark Byers made a good point, actually: this may not be what you really want. If what you really care about is whether a number rounded to the nearest two decimal places is an integer, you could do this instead:

public static bool IsNearlyInteger(double number) {
    return Math.Round(number, 2) == Math.Round(number);
}

There are any number of ways to do this. For example:

double d = 5.0;
bool isInt = d == (int)d;

You can also use modulo.

double d = 5.0;
bool isInt = d % 1 == 0;

Try this:

number == Convert.ToInt16(number);

Whilst the solutions proposed appear to work for simple examples, doing this in general is a bad idea. A number might not be exactly an integer but when you try to format it, it's close enough to an integer that you get 1.000000. This can happen if you do a calculation that in theory should give exactly 1, but in practice gives a number very close to but not exactly equal to one due to rounding errors.

Instead, format it first and if your string ends in a period followed by zeros then strip them. There are also some formats that you can use that strip trailing zeros automatically. This might be good enough for your purpose.

double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));

Output:

1
1.02

If upper and lower bound of Int32 matters:

public bool IsInt32(double value)
{
    return  value >= int.MinValue && value <= int.MaxValue && value == (int)value;
}

Using int.TryParse will yield these results:

        var shouldBeInt = 3;

        var shouldntBeInt = 3.1415;

        var iDontWantThisToBeInt = 3.000f;

        Console.WriteLine(int.TryParse(shouldBeInt.ToString(), out int parser)); // true

        Console.WriteLine(int.TryParse(shouldntBeInt.ToString(), out parser)); // false

        Console.WriteLine(int.TryParse(iDontWantThisToBeInt.ToString(), out parser)); // true, even if I don't want this to be int

        Console.WriteLine(int.TryParse("3.1415", out  parser)); // false

        Console.WriteLine(int.TryParse("3.0000", out parser)); // false

        Console.WriteLine(int.TryParse("3", out parser)); // true

        Console.ReadKey();

Mark Rushakoff's answer may be simpler, but the following also work and may be more efficient since there is no implicit division operation:

     bool isInteger = (double)((int)f) == f ;

and

     bool isInteger = (decimal)((int)d) == d ;

If you want a single expression for both types, perhaps

     bool isInteger = (double)((int)val) == (double)val ;

static bool IsWholeNumber(double x) 
{
    return Math.Abs(x % 1) < double.Epsilon;
}

You can use String formatting for the double type. Here is an example:

double val = 58.6547;
String.Format("{0:0.##}", val);      
//Output: "58.65"

double val = 58.6;
String.Format("{0:0.##}", val);      
//Output: "58.6"

double val = 58.0;
String.Format("{0:0.##}", val);      
//Output: "58"

Let me know if this doesn't help.


Perhaps not the most elegant solution but it works if you are not too picky!

bool IsInteger(double num) {
    return !num.ToString("0.################").Contains(".");
}

I faced a similar situation, but where the value is a string. The user types in a value that's supposed to be a dollar amount, so I want to validate that it's numeric and has at most two decimal places.

Here's my code to return true if the string "s" represents a numeric with at most two decimal places, and false otherwise. It avoids any problems that would result from the imprecision of floating-point values.

try
{
    // must be numeric value
    double d = double.Parse(s);
    // max of two decimal places
    if (s.IndexOf(".") >= 0)
    {
        if (s.Length > s.IndexOf(".") + 3)
            return false;
    }
    return true;
catch
{
    return false;
}

I discuss this in more detail at http://progblog10.blogspot.com/2011/04/determining-whether-numeric-value-has.html.


bool IsInteger(double num) {
    if (ceil(num) == num && floor(num) == num)
        return true;
    else
        return false;
}

Problemo solvo.

Edit: Pwned by Mark Rushakoff.