Hashcode implementation double precision

人走茶凉 提交于 2019-12-06 02:36:44

问题


I've asked a question about this class before, but here is one again.

I've created a Complex class:

 public class Complex
 {
        public double Real { get; set; }
        public double Imaginary { get; set; }
 }

And I'm implementing the Equals and the Hashcode functions, and the Equal function takes in account a certain precision. I use the following logic for that:

    public override bool Equals(object obj)
    {
        //Some default null checkint etc here, the next code is all that matters.
        return Math.Abs(complex.Imaginary - Imaginary) <= 0.00001 &&
            Math.Abs(complex.Real - Real)  <= 0.00001;
    }

Well this works, when the Imaginary and the Real part are really close to each other, it says they are the same.

Now I was trying to implement the HashCode function, I've used some examples John skeet used here, currently I have the following.

    public override int GetHashCode()
    {
        var hash = 17;
        hash = hash*23 + Real.GetHashCode();
        hash = hash*23 + Imaginary.GetHashCode();
        return hash;
    }

However, this does not take in account the certain precision I want to use. So basically the following two classes:

Complex1[Real = 1.123456; Imaginary = 1.123456]

Complex2[Real = 1.123457; Imaginary = 1.123457]

Are Equal but do not provide the same HashCode, how can I achieve that?


回答1:


First of all, your Equals() implementation is broken. Read here to see why.

Second, such a "fuzzy equals" breaks the contract of Equals() (it's not transitive, for one thing), so using it with Hashtable will not work, no matter how you implement GetHashCode().

For this kind of thing, you really need a spatial index such as an R-Tree.




回答2:


Just drop precision when you calculate the hash value.

public override int GetHashCode()
{
    var hash = 17;
    hash = hash*23 + Math.Round(Real, 5).GetHashCode();
    hash = hash*23 + Math.Round(Imaginary, 5).GetHashCode();
    return hash;
}

where 5 is you precision value




回答3:


I see two simple options:

  • Use Decimal instead of double
  • Instead of using Real.GetHashCode, use Real.RoundTo6Ciphers().GetHashCode().

Then you'll have the same hashcode.




回答4:


I would create read-only properties that round Real and Imaginary to the nearest hundred-thousandth and then do equals and hashcode implementations on those getter properties.



来源:https://stackoverflow.com/questions/5703602/hashcode-implementation-double-precision

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!