有没有一种方法来得到一个与epsilon的float的哈希码? [英] Is there a way to get a hashcode of a float with epsilon?
问题描述
< ($ obj == null){
return false; code> public override bool Equals(object obj)
{
if(obj == null) $(
)
if(GetType()!= obj.GetType()){
return false;
}
float d = DistSq((Vec)obj);
return IsConsideredZero(d);
}
public float DistSq(Vec p)
{
Vec d = this - p;
return d.LengthSq();
public float LengthSq()
{
return X * X + Y * Y + Z * Z;
}
private const float VEC_COMPARE_EPSILON_ABS = 1E-05f;
public static bool IsConsideredZero(float f)
{
return Math.Abs(f)< VEC_COMPARE_EPSILON_ABS;
$ / code>
到目前为止,一切正常。但是,现在我想要得到一个向量的哈希码。我可以看到像 hash =(int)X ^(int)Y ^(int)Z
这样的东西肯定会失败。
最好的办法是:
$ b $ pre $ public override int GetHashCode()
{
返回0;
}
当然,这样做很糟糕。有什么办法可以得到一个合理的哈希码? NaNs和其他特殊的价值是可能的,但不太可能,万一这一点很重要。
假设你想拥有正常的hashcode / equal属性:
$ ul
如果X = Y和Y = Z那么X = Z(传递性)
第一个规则是问题 - 因为如果每个值被认为与下一个更大的可表示数字相等,那么最后所有的数字都是相等的。例如,假设一个数字与另一个数字相等,它们在0.1之内:
<0>等于0.08
0.08等于0.16
0.16等于0.24
=> 0等于传统性规则$ 0.16,传递性规则
=> 0等于0.24
(等)
如果你忽略了传递规则,那么你仍然(可能)想要相等的值有相同的hashcode。这有效地强制了传递规则 - 在上面的例子中,0和0.08必须具有相同的哈希码,0和0.16也是一样。因此0和0.16必须具有相同的哈希码,等等。因此,你可以没有有用的哈希码 - 它必须是一个常量。
It is well known that comparing floats by == is usually a mistake. In a 3D-vector class (with float components X, Y, Z) i wrote, two vectors are considered equal if their distance is considered zero.
public override bool Equals(object obj)
{
if (obj == null) {
return false;
}
if (GetType () != obj.GetType ()) {
return false;
}
float d = DistSq ((Vec) obj);
return IsConsideredZero (d);
}
public float DistSq(Vec p)
{
Vec d = this - p;
return d.LengthSq ();
}
public float LengthSq()
{
return X * X + Y * Y + Z * Z;
}
private const float VEC_COMPARE_EPSILON_ABS = 1E-05f;
public static bool IsConsideredZero(float f)
{
return Math.Abs (f) < VEC_COMPARE_EPSILON_ABS;
}
So far, everything worked fine. However, now i'd like to get a hashcode of the vector. I can see that something like hash = (int)X^(int)Y^(int)Z
is bound to fail.
The best i could come up with was:
public override int GetHashCode()
{
return 0;
}
This, of course, kind of sucks. Is there any way to get a reasonable hashcode? NaNs and other special values are possible, but unlikely, in case that is important.
It's impossible assuming you want to have the normal hashcode/equality properties:
- If X = Y and Y = Z then X = Z (transitivity)
- If X = Y then Y = X (commutivity)
- X = X for all X (reflexivity)
The first rule is the problem - because if each value is deemed "equal" to the next greater representable number, you end up with all numbers being equal. For instance, suppose a number is deemed equal to another they're within 0.1:
0 equals 0.08 0.08 equals 0.16 0.16 equals 0.24
=> 0 equals 0.16 by the transitivity rule => 0 equals 0.24 by the transitivity rule
(etc)
If you ignore the transitivity rule, then you still (presumably) want "equal" values to have equal hashcodes. This effectively enforces the transitivity rule - in the above example, 0 and 0.08 have to have equal hashcodes, as do 0 and 0.16. Therefore 0 and 0.16 have to have equal hashcodes, and so on. Therefore you can have no useful hashcode - it has to be a constant.
这篇关于有没有一种方法来得到一个与epsilon的float的哈希码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!