This answer is based on the top-voted one here: Floating point comparison functions for C#
There are edge cases to be accounted for that preclude direct comparsion, as shown here. Basically because decimals could be equal, but not actually seen as equal by code, i.e.
float a = 0.15 + 0.15
float b = 0.1 + 0.2
if (a == b) { ... } // can be false!
if (a >= b) { ... } // can also be false!
You have to specify how close you want to compare the numbers. The answer given at the link terms that as an "Epsilon", but they didn't go into detail on if that was placevalues, a range, or simply an increment of the numbers given.
The "Epsilon" in the following function will compare the numbers to within the given degree of difference from each other. Ex., if you wanted to use the above example and make it come back as true, you would want to compare within 0.1 of each other, not 0.01, like it would do by default when comparing 0.30 to 0.3.
public static bool nearlyEqual(double a, double b, double epsilon)
{
double absA = Math.Abs(a);
double absB = Math.Abs(b);
double diff = Math.Abs(a - b);
if (a == b)
{
// shortcut, handles infinities
return true;
}
else if (a == 0 || b == 0 || diff < Double.Epsilon)
{
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < epsilon;
}
else
{
// use relative error
return diff / (absA + absB) < epsilon;
}
}
Say you have a Dictionary of items with an item ID and a floating-point decimal (double) number, like a bunch of latitudes...
Dictionary<int, double> cityLatPoints = new Dictionary<int, double>();
And you want to know if a latitude is near one of those points... here's how you'd do that:
double epsilon = 0.000005;
List<int> possLatCityIds = new List<int>(); // stores your matching IDs for later
double dblLat = 39.59833333; // hard-coded value here, but could come from anywhere
// Possible Latitudes
foreach (KeyValuePair<int, double> kvp in cityLatPoints)
{
if (nearlyEqual(kvp.Value, dblLat, epsilon))
{
//Values are the same or similar
possLatCityIds.Add(kvp.Key); // ID gets added to the list
}
}
For the example given, it would look like this:
decimal valOne = decimal.Round(valueOne, 6);
decimal valTwo = decimal.Round(valueTwo, 6);
double dblOne = Convert.ToDouble(valOne);
double dblTwo = Convert.ToDouble(valTwo);
double epsilon = 0.0000001;
if (nearlyEqual(dblOne, dblTwo, epsilon))
{
Console.WriteLine("Values are equal");
}
else
{
Console.WriteLine("Values are different");
}