哈希码实现双精度
我之前曾问过关于这门课的问题,但这里又问了一个。
我创建了一个 Complex 类:
public class Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
并且我正在实现 Equals
和 Hashcode
函数,并且 Equal 函数考虑了一定的精度。我使用以下逻辑:
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;
}
嗯,这是有效的,当虚部和实部非常接近时,它表示它们是相同的。
现在我正在尝试实现 HashCode 函数,我使用了 John skeet 此处使用的一些示例,目前我有以下示例。
public override int GetHashCode()
{
var hash = 17;
hash = hash*23 + Real.GetHashCode();
hash = hash*23 + Imaginary.GetHashCode();
return hash;
}
但是,这没有考虑到我想要使用的特定精度。所以基本上有以下两个类:
Complex1[Real = 1.123456;虚数 = 1.123456]
复数2[实数 = 1.123457; Imaginary = 1.123457]
Equal
但不提供相同的 HashCode
,我该如何实现?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,您的
Equals()
实现已损坏。请阅读此处了解原因。其次,这样的“模糊等于”破坏了
Equals()
的约定(一方面,它不是传递性的),因此将其与Hashtable
一起使用将不起作用,无论您如何实现GetHashCode()
。对于这种事情,您确实需要一个空间索引,例如 R-Tree。
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 withHashtable
will not work, no matter how you implementGetHashCode()
.For this kind of thing, you really need a spatial index such as an R-Tree.
计算哈希值时只需降低精度即可。
其中
5
是您的精度值Just drop precision when you calculate the hash value.
where
5
is you precision value我看到两个简单的选项:
然后你将拥有相同的哈希码。
I see two simple options:
Then you'll have the same hashcode.
我将创建只读属性,将实数和虚数四舍五入到最接近的万分之一,然后对这些 getter 属性执行 equals 和 hashcode 实现。
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.