gpt4 book ai didi

floating-point - 有没有办法用 epsilon 获取 float 的哈希码?

转载 作者:行者123 更新时间:2023-12-04 00:04:58 25 4
gpt4 key购买 nike

众所周知,通过 == 比较 float 通常是一个错误。在我写的 3D 向量类(带有浮点分量 X、Y、Z)中,如果两个向量的距离为零,则认为它们相等。

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;
}
到目前为止,一切正常。但是,现在我想获得向量的哈希码。我可以看到类似 hash = (int)X^(int)Y^(int)Z 的内容注定要失败。
我能想到的最好的是:
public override int GetHashCode()
{
return 0;
}
当然,这有点糟糕。有没有办法获得合理的哈希码? NaN 和其他特殊值是可能的,但不太可能,以防万一。

最佳答案

假设您想要拥有正常的哈希码/相等属性,这是不可能的:

  • 如果 X = Y 且 Y = Z,则 X = Z(传递性)
  • 如果 X = Y 那么 Y = X(交换性)
  • X = X 对于所有 X(自反性)

  • 第一条规则是问题 - 因为如果每个值都被视为与下一个更大的可表示数字“相等”,则最终所有数字都相等。例如,假设一个数字被认为等于另一个它们在 0.1 以内:

    0 等于 0.08
    0.08 等于 0.16
    0.16 等于 0.24

    => 0 根据传递性规则等于 0.16
    => 0 根据传递性规则等于 0.24

    (等)

    如果您忽略传递规则,那么您仍然(大概)希望“相等”值具有相等的哈希码。这有效地强制执行了传递规则——在上面的例子中,0 和 0.08 必须具有相同的哈希码,0 和 0.16 也是如此。因此 0 和 0.16 必须具有相同的哈希码,依此类推。因此,您可能没有有用的哈希码——它必须是一个常量。

    关于floating-point - 有没有办法用 epsilon 获取 float 的哈希码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/580905/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com