gpt4 book ai didi

java - 为具有浮点成员的类实现 "tolerant" `equals` & `hashCode`

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:56:04 26 4
gpt4 key购买 nike

我有一个带有 float 字段的类。例如:

public class MultipleFields {
final int count;
final float floatValue;

public MultipleFields(int count, float floatValue) {
this.count = count;
this.floatValue = floatValue;
}

}

我需要能够按值比较实例。现在我该如何正确实现 equalshashCode

实现equalshashCode 的常用方法是只考虑所有字段。例如。 Eclipse 将生成以下 equals:

  public boolean equals(Object obj) {
// irrelevant type checks removed
....
MultipleFields other = (MultipleFields) obj;
if (count != other.count)
return false;
if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
return false;
return true;
}

(和一个类似的hashCode,本质上是计算count* 31 + Float.floatToIntBits(floatValue))。

问题是我的 FP 值容易出现舍入误差(它们可能来自用户输入、数据库等)。所以我需要一个“宽容”的比较。

常见的解决方案是使用 epsilon 值进行比较(参见例如 Comparing IEEE floats and doubles for equality )。但是,我不太确定如何使用此方法实现 equals,并且仍然有一个与 equals 一致的 hashCode

我的想法是定义用于比较的有效位数,然后在 equalshashCode 中始终舍入到该位数:

long comparisonFloatValue = Math.round(floatValue* (Math.pow(10, RELEVANT_DIGITS)));

然后,如果我在 equalshashCode 中用 comparisonFloatValue 替换所有对 floatValue 的使用,我应该得到一个“容忍”比较,与hashCode一致。

  • 这行得通吗?
  • 您认为这种方法有什么问题吗?
  • 有更好的方法吗?看起来比较复杂。

最佳答案

最大的问题是两个浮点值可能仍然非常接近但仍然比较不相等。基本上,您将浮点值的范围划分为桶 - 两个值可能非常接近而不在同一个桶中。假设您正在使用两位有效数字,应用截断来获取存储桶,例如...那么 11.999999 和 12.000001 将不相等,但 12.000001 和 12.9999999 将相等,尽管彼此相距很远。

不幸的是,如果您像这样存储值,由于传递性,您不能适本地实现 equals:x 和 y 可能靠得很近,y 和 z 可能靠得很近,但是这并不意味着 x 和 z 靠得很近。

关于java - 为具有浮点成员的类实现 "tolerant" `equals` & `hashCode`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4386877/

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