Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if a decimal/double is an integer?

Tags:

c#

People also ask

Can a double be an integer?

The answer is no, because any integer which converts back and forth to the same value, actually represents the same integer value in double.

Is a decimal an integer?

Fractions and decimals are not integers. All whole numbers are integers (and all natural numbers are integers), but not all integers are whole numbers or natural numbers.


For floating point numbers, n % 1 == 0 is typically the way to check if there is anything past the decimal point.

public static void Main (string[] args)
{
    decimal d = 3.1M;
    Console.WriteLine((d % 1) == 0);
    d = 3.0M;
    Console.WriteLine((d % 1) == 0);
}

Output:

False
True

Update: As @Adrian Lopez mentioned below, comparison with a small value epsilon will discard floating-point computation mis-calculations. Since the question is about double values, below will be a more floating-point calculation proof answer:

Math.Abs(d % 1) <= (Double.Epsilon * 100)

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;

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);
}

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