Reputation: 1357
The following code in C# doesn't work:
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
So, the question: what's the best way to compare Double and Int?
Upvotes: 31
Views: 43731
Reputation:
It's an exceedingly bad idea to compare integers and floating-point numbers for equality in any language. It works for very simple cases, but after you do any math at all, the likelihood of the program doing what you want it to decrease dramatically.
It has to do with the way floating-point numbers are stored on a binary, digital system.
If you are very sure you want to use this, create a class to make your own number with fractions. Use one int to maintain the whole number, and another int to maintain the fraction.
Upvotes: 4
Reputation: 131806
You really can't compare floating point and integral values in a naive way; particularly, since there's the classic floating point representation challenges. What you can do is subtract one from the other and see if the difference between them is less than some precision you care about, like so:
int iValue = 0;
double dValue = 0.0;
var diff = Math.Abs(dValue - iValue);
if( diff < 0.0000001 ) // need some min threshold to compare floating points
return true; // items equal
You really have to define for yourself what equality
means to you. For example, you may want a floating point value to round towards the nearest integer, so that 3.999999981 will be "equal" to 4. Or you may want to truncate the value, so it would effectively be 3. It all depends on what you're trying to achieve.
EDIT: Note that I chose 0.0000001 as an example threshold value ... you need to decide for yourself what precision is sufficient for comparison. Just realize you need to be within the normal representational bounds of double
which I believe is defined as Double.Epsilon
.
Upvotes: 58
Reputation: 1
If you have not done any calculations using the double, you can just use ==
. This is because an integer can be represented by a double exactly (only between -2^53 and 2^53).
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue == dValue;
This returns true.
The reason why Equals
doesn't work is that the ==
operator will automatically convert the integer to a double before comparison, whereas Equals
won't and thus fails.
This answer has more information: https://stackoverflow.com/a/52525223/15714398
If you have done calculations using the double, all bets are off and you have to do some analysis of the number of significant figures in your calculations.
Upvotes: 0
Reputation: 1
Because Epsilon defines the minimum expression of a positive value whose range is near zero, the margin of difference between two similar values must be greater than Epsilon. Typically, it is many times greater than Epsilon. Because of this, we recommend that you do not use Epsilon when comparing Double values for equality.
Upvotes: 0
Reputation: 17
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
// Put your code here
}
OR
if((val2 - Double.Epsilon) < 0)
{
// Put your code here
}
where Double.Epsilon is lowest possible value for Double.
Upvotes: 0
Reputation: 81267
Nowadays, just about the only time one should be comparing values of types double
and either integer
or long
for strict equality is when, for some reason, one is stuck storing or passing integral quantities as floating-point values and later needs to convert them back. Such conversion may in most cases be most easily accomplished by casting the integral type to double
, and then comparing the result of that cast. Note that conversion from long
to double
may be imprecise if the number is outside the range ±252. Nonetheless, in the days before 64-bit long
became available, double
was a handy storage type for integer quantities which were too big for a 32-bit int
but small enough to be handled by double
.
Note that converting a long
to double
and then doing the comparison will yield an "equal" result if the nominal value of the double
doesn't precisely match the long
value, but represents the closest possible double
to that value. This behavior makes sense if one recognizes that floating-point types don't actually represent a single precise value, but rather a range of values.
Upvotes: 0
Reputation: 14851
This really depends on what you consider "equal". If you want your comparison to return true if and only if the double precisely matches the integer value (i.e. has no fractional component), you should cast your int to a double to do the comparison:
bool isEqual = (double)iValue == dValue;
If something like 1.1 would be considered equal to 1, you can either cast the double to an int (if you want to ignore the fractional component altogether) or round the double if you want say 1.9 to equal 2.
Upvotes: 1