Java Float.equals(几乎)完全无用吗?我应该用什么来代替?

Java Float.equals(几乎)完全无用吗?我应该用什么来代替?,java,Java,考虑到: 看起来Float.equals在它当前的形式中几乎是完全无用的 我是否遗漏了一些东西,或者在某些情况下使用Float.equals是合适的,除非在非常罕见的情况下,您希望测试二进制相等性 如果是这样的话,是否真的完成了滚动您自己的identikit epsilon函数(如第一个链接中所建议的),或者是否有一个现有的包装器用于这个惊人的常见操作 另外,Double/Float.compare是否也存在同样的问题,或者是否存在一个采用ε的现有比较器 (请注意,我无法将现有库从Flo

考虑到:

看起来Float.equals在它当前的形式中几乎是完全无用的

我是否遗漏了一些东西,或者在某些情况下使用Float.equals是合适的,除非在非常罕见的情况下,您希望测试二进制相等性

如果是这样的话,是否真的完成了滚动您自己的identikit epsilon函数(如第一个链接中所建议的),或者是否有一个现有的包装器用于这个惊人的常见操作

另外,Double/Float.compare是否也存在同样的问题,或者是否存在一个采用ε的现有比较器


(请注意,我无法将现有库从Float更改为BigD)

Float.equals如果您确定要自己比较Float,则它是无用的,但它也会检查参数的类型,并且是自反的。例如,不要忘记在集合中自动调用
equals

以下是源代码:

public boolean equals(Object obj) {
    return (obj instanceof Float)
           && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
这允许
Float
的任何实例(包括
newfloat(“NaN”)
)与其自身相等,这是它的一部分,
newfloat(-0”)
与可能有用的
newfloat(“0”)
不同(并且与
hashCode
一致)


至于第二部分:在处理实际问题时,epsilon与某些上下文或物理维度无关的情况并不多(或者您可能不应该使用
Float
,而应该使用
BigDecimal
)。从语义上讲,浮点数的相等实际上没有意义。充其量您对距离感兴趣。

可能与@Blip重复请参见我问题的第2部分,因为该链接中的建议是滚动您自己的identikit静态函数,该函数将与执行此操作的所有其他静态函数相同。这是Double/Float.equals与==”的终极对立。从文档中可以看出,Double/Float.equals所做的只是与==”进行比较,然后再次检查文档。他们实际上是不同的。例如,
equals
为NaNs返回true,而
=
不返回true。@Radiodef我不确定“出错”是否有用。(或者2.7 equaling NaN是否有某种意义我不知道)?想想
a.equals(a)
返回false的假设行为。因此,它的目的是作为一个值比较,以便集合能够正确地运行(例如)。“这个定义允许哈希表正常运行。”这是一个有点狭隘的目的,但并非毫无用处。这正是我的观点。如果Float上的equals不可靠,那么您当然也不能在集合中依赖它(例如,您认为在集合中添加“9”和“18/2”将检测到冲突,但当然不会)。那么,
equals
必须实现以防万一,这并不意味着您通常应该使用计算的浮点实例作为键。@deworde,这取决于您对浮点运算的期望。可能更普遍的情况是,我们不应该在HashMap/HashSet中使用Float/Double作为键。@对于第二部分,在这种情况下,在Float上有一个可设置的epsilon,或者至少有一个函数Math.arithmaticeequals(f1,f2,epsilon)难道没有意义吗?毕竟,这个函数实际上就是每个答案所暗示的,为什么它不是库的一部分呢?@deworde从语义上讲,浮点数的相等并没有真正的意义。你需要的通常是一段距离,阈值实际上取决于你的问题和目标。