IEqualityComparer <double> with tolerance; How to implement GetHashCode?
I implement a reusable DoubleEqualityComparer (with user tolerance: the "epsilon" constructor parameter) to facilitate the use of LINQ with double sequences. For instance:
bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01));
What is the correct way to implement GetHashCode? Here is the code:
public class DoubleEqualityComparer : IEqualityComparer<double>, IEqualityComparer<double?>
{
private readonly double epsilon;
public DoubleEqualityComparer(double epsilon)
{
if (epsilon < 0)
{
throw new ArgumentException("epsilon can't be negative", "epsilon");
}
this.epsilon = epsilon;
}
public bool Equals(double x, double y)
{
return System.Math.Abs(x - y) < this.epsilon;
}
public int GetHashCode(double obj)
{
// ?
}
}
PS: I can always return the same value (for example: GetHashCode (double obj) {return 0;}) to always force the Equals (double, double) method (not very strong, I know), but I remember that this solution causes problems when a comparison is used with a dictionary ...
+5
2 answers
, EqualityComparer - . .
, Any + :
private static bool DoublesAreNearlyEquals(double d1, double d2, double epsilon = 0.01D)
{
return System.Math.Abs(d1 - d2) < this.epsilon;
}
private void foo()
{
var myDoubles = Getdoubles();
var doubleToSearch = 42D;
var result = myDoubles.Any(d=>DoublesAreNearlyEquals(d, doubleToSearch));
}
+4