Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What would be implementation GetHashCode() for IEqualityComparer<double>

Tags:

c#

.net

hashcode

I am looking for simple implementation of GetHashCode() method for following class.

public class EpsilonEqualityComparer : IEqualityComparer<double>
{
    private readonly double _epsilon;
    public EpsilonEqualityComparer(double epsilon)
    {
        _epsilon = epsilon;
    }

    public bool Equals(double x, double y)
    {
        return Math.Abs(x - y) < _epsilon;
    }

    public int GetHashCode(double obj)
    {
        ...
    }
}

Of course trivial implementation would be something like return Math.Sign(obj). Nevertheless I am looking for something more practical. Do you have any idea?

like image 421
Jakub Šturc Avatar asked Dec 11 '22 03:12

Jakub Šturc


2 Answers

This breaks the specification of IEqualityComparer<> even before you have to worry about GetHashCode.

For an equality check, you need x == y && y == z to imply x == z but this is not true for your Equals implementation. For example, with an epsilon of 1, you have 1 == 1.9 and 1.9 == 2.8 but not 1 == 2.8.

(You also require x == x, and x == y to imply y == x, but your equality check is fine with those.)

like image 138
Rawling Avatar answered Dec 13 '22 15:12

Rawling


I am afraid my answer to this will be analoguous to this: How to implement GetHashCode for this situation?

However in your case the situation is not so obvious. It looks like you have a properly defined equality condition, but it might not be.

In the other answer I referred to MSDN stating:

(x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.

Now, say you have three numbers:

x = anything
y = x + epsilon
z = y + epsilon // == x + 2 * epsilon

Then x.Equals(y) and y.Equals(z) but x does not equal z.

Because of that you won't end up with properly defined distinct equality sets, and you can't assign those sets any hashcode numbers.

like image 36
chiccodoro Avatar answered Dec 13 '22 16:12

chiccodoro