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.
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
bool IsInteger(double num) {
if (ceil(num) == num && floor(num) == num)
return true;
else
return false;
}
Problemo solvo.
Edit: Pwned by Mark Rushakoff.