首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试浮点相等。(FE_FLOATING_POINT_EQUALITY)

测试浮点相等。(FE_FLOATING_POINT_EQUALITY)
EN

Stack Overflow用户
提问于 2010-10-01 00:13:34
回答 3查看 33.2K关注 0票数 22

我在ANT脚本中使用了findbugs,但我不知道如何修复其中的两个错误。我已经看过文档了,但是我不明白。以下是我的错误和相应的代码:

错误1:测试浮点相等。(FE_FLOATING_POINT_EQUALITY)

代码语言:javascript
复制
private boolean equals(final Quantity other) {
    return this.mAmount == convertedAmount(other);
}

错误2: EQ_COMPARETO_USE_OBJECT_EQUALS

代码语言:javascript
复制
public final int compareTo(final Object other) {
    return this.description().compareTo(((Decision) other).description());
}

我已经阅读了ComparesTo问题的文档,说明

强烈建议(x.compareTo(y)==0) == (x.equals(y)),但不是严格要求。一般而言,任何实现可比较接口并违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:这个类有一个与equals不一致的自然排序。”

以及有关浮点相等的文档。

此操作比较两个浮点值是否相等。由于浮点计算可能涉及舍入,因此计算的浮点值和双精度值可能不准确。对于必须精确的值,如货币值,请考虑使用固定精度类型,如BigDecimal。对于不需要精确的值,考虑在某个范围内比较相等,例如: if ( Math.abs(x - y) < .0000001 )。请参阅Java语言规范,第4.2.4节。

不过我还是不明白。有人能帮帮忙吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-04 02:12:51

问题1:

对于FE_FLOATING_POINT_EQUALITY问题,您不应该直接使用==运算符比较两个浮点值,因为由于微小的舍入误差,即使条件value1 == value2不成立,对于您的应用程序来说,这两个值可能在语义上“相等”。

要解决此问题,请修改代码,如下所示:

代码语言:javascript
复制
private boolean equals(final Quantity other) {
    return (Math.abs(this.mAmount - convertedAmount(other)) < EPSILON);
}

其中EPSILON是您应该在代码中定义的常量,表示您的应用程序可以接受的微小差异,例如.0000001。

问题2:

对于EQ_COMPARETO_USE_OBJECT_EQUALS问题:强烈建议在x.compareTo(y)返回零的地方,x.equals(y)应该为true。在您的代码中,您已经实现了compareTo,但是您没有覆盖equals,所以您从Object继承了equals的实现,并且不满足上述条件。

为了解决这个问题,在你的类中重写equals (也许还有hashCode),这样当x.compareTo(y)返回0时,x.equals(y)将返回true

票数 19
EN

Stack Overflow用户

发布于 2010-10-01 01:28:24

对于浮点警告,您应该记住,浮点数是一种不精确的类型。为此经常给出的一个标准参考(也许值得一读)是:

大卫·戈德堡的。

因为浮点数不是精确值-即使它们向上舍入到几个小数时看起来是一样的-它们可能会有很小的差异,并且无法匹配。

Comparable interface期望实现者的特定行为;警告是告诉您没有遵守该行为,并提供了建议的操作。

票数 6
EN

Stack Overflow用户

发布于 2015-04-21 21:53:22

我不同意上面的答案。Equals和compareTo是在浮点比较中引入epsilon的错误位置。

只需使用"==“运算符,就可以通过equals和compareTo精确地比较浮点值。

如果您的应用程序使用的浮点数是calculation的结果,则需要将这些值与epsilon方法进行比较,它应该只在需要这样做的地方进行比较。例如在数学交线方法中。

但不是在equals和compareTo中。

此警告具有很强的误导性。这意味着比较两个浮点数,其中至少一个是计算的结果,可能会得到意想不到的结果。但是,通常情况下,这样的浮点数并不是计算的结果,比如

代码语言:javascript
复制
static final double INVALID_VALUE = -99.0;
if (f == INVALID_VALUE)

其中f是用INVALID_VALUE初始化的,在java中总是可以完美地工作。但是findbugs和sonarcube仍然会抱怨。

因此,只需添加一个忽略过滤器来查找错误,假设您有两个类MyPoint2D和Myrectangle2D

代码语言:javascript
复制
<Match>
        <OR>
            <Class name="~.*\.MyPoint2D" />
            <Class name="~.*\.MyRectangle2D" />
        </OR>
        <Bug code="FE" />
        <Justification author="My Name" />
        <Justification
            text="Floating point equals works (here)." />
    </Match>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3832592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档