这个是二元和原始专家。我正在实现一个浮点R3向量结构和我对#34;相等的定义"实际上"大多数是平等的。"具体地,对于所比较的矢量的所有坐标,Abs((a [i] - b [i])/(a [i] + b [i]))< .00001返回true。
private static bool FloatEquality(float a, float b)
{
if (a == b)
{
return true;
}
else
{
float e;
try
{
e = (b - a) / (b + a);
}
catch (DivideByZeroException)
{
float g = float.Epsilon;
e = (b - a) / g;
}
//AppConsole.AppConsole.Instance.WriteLine(e);
if (e < .00001f && e > -.00001f)
{
return true;
}
else
{
return false;
}
}
}
我的问题在于确定是否有办法让哈希值在满足此要求的向量上出现相同,因为我希望能够将这些向量用作&#34;密钥&#34;对于词典。
如您所见,上面的代码用于检查3个不同坐标的相等性。
我正在考虑从三个浮点坐标中提取字节并使用每个浮点坐标中的两个。
(以下不是代码,但Stack Overflow不会让我发布它,除非我缩进它)
Vector(x,y,z):
x's float byte[] = [ x1 x2 x3 x3 ]
y's float byte[] = [ y1 y2 y3 y4 ]
z's float byte[] = [ z1 z2 z3 z4 ]
Hash code: byte[] {x2^x3 , y2^y3, z2 ^ z3, x2 ^ z3}
或类似的东西...简而言之 - 我很好奇如何确保适合我的equals方法的向量的哈希码总是会出现相同的...如果有人有一个非常低的好主意成本计算,我很乐意听到它。或者,如果你可以引导我到一个更深入讨论如何存储浮点数的地方,以及如果上面的比较方法返回相等的话,哪些字节总是相同的。
我可能需要一个新的比较方法而不是哈希函数,因为我无法确定任何字节是否匹配我猜...
答案 0 :(得分:1)
嗯,基本的想法很简单 - 你必须人为地降低花车的精度。如何有效地完成这项工作在很大程度上取决于您期望看到的数据类型。
例如,如果你主要使用小值,你可以简单地使用这样的东西:
(int)Math.Round(x1 * 1000)
^ (int)Math.Round(x2 * 1000)
^ (int)Math.Round(x3 * 1000)
请注意,虽然我实际上并未实现您的if (e < .00001f && e > -.00001f)
条件,但这并不重要 - 我们的想法是减少冲突,并确保相同的值具有相同的哈希值码。不必(或可能)也不必确保不相等的值不具有相等的哈希码。其余的应该在Equals
,==
等的覆盖中处理 - 必须存在严格的相等性检查。与Equals
和公司不同,GetHashCode()
只有有关于单个向量的数据,因此您甚至无法使用来自多个单一向量的数据那里。
哈希码只是偶尔发生关键冲突。因此,如果您的每个向量都会在Dictionary
中返回0
,那么GetHashCode()
仍会有效 - 只是表现会受到影响。只要等向量最终具有相同的哈希码,哈希码就可以满足您的需求:)
当然,最好的方法就是不使用向量作为字典中的键。找到您感兴趣的向量部分(最有帮助),并将其用作关键字。也许你会发现Dictionary
实际上并不是你想要的东西(例如,在游戏中,有大量不同的空间分区方法可以用于向量 - 来自简单的网格状布局,通过手动空间分区,直到像BSP这样的东西。