Jakub Šturc
Jakub Šturc

Reputation: 35767

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

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?

Upvotes: 4

Views: 380

Answers (2)

chiccodoro
chiccodoro

Reputation: 14716

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.

Upvotes: 6

Rawling
Rawling

Reputation: 50104

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.)

Upvotes: 7

Related Questions