Test for floating point equality. (FE_FLOATING_POINT_EQUALITY)

僤鯓⒐⒋嵵緔 提交于 2019-11-26 16:38:18

Problem 1:

For the FE_FLOATING_POINT_EQUALITY issue, you should not be comparing two float values directly with the == operator, since due to tiny rounding errors, the values might be semantically "equal" for your application even if the condition value1 == value2 does not hold true.

In order to fix this, modify your code as follows:

private boolean equals(final Quantity other) {
    return (Math.abs(this.mAmount - convertedAmount(other)) < EPSILON);
}

Where EPSILON is a constant that you should define in your code, and represents small differences that are acceptable to your application, e.g. .0000001.

Problem 2:

For the EQ_COMPARETO_USE_OBJECT_EQUALS issue: It is strongly recommended that wherever x.compareTo(y) returns zero, x.equals(y) should be true. In your code you have implemented compareTo, but you have not overriden equals, so you are inheriting the implementation of equals from Object, and the above condition is not met.

In order to fix this, override equals (and perhaps hashCode) in your class, so that when x.compareTo(y) returns 0, then x.equals(y) will return true.

For the floating point warning, you should bear in mind that floats are an inexact type. A standard reference oft given for this (which is worth reading once perhaps) is:

What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg.

Because floats are not exact values - even if they look the same when rounded up to a few decimals - they can differ very slightly, and fail to match.

The Comparable interface expects a certain behaviour by its implementor; the warning is telling you you are not adhering to that, and offering suggested actions.

I do not agree with the answers above. Equals and compareTo are the wrong place to introduce epsilons in floating point comparisons.

Floating point values can be compared exactly by equals and compareTo, just using the "==" operator.
If your application, uses floats that are a result of calculation, need to compare these values with the epsilon approach, it should do that only in that place where this is needed. E.g in a mathematical line intersection method.
But not in equals and compareTo.

This warning is very misleading. It means comparing two floats where at leats one is a result of an calculation might give unexpected result. However, often such floats, to compare, are not a result of a calculation, like

static final double INVALID_VALUE = -99.0;
if (f == INVALID_VALUE)

where f is initialized with INVALID_VALUE, will in java always work perfectly. But findbugs and sonarcube will still complain.

So just add an ignore filter to findbugs, asuming you have two classes MyPoint2D and Myrectangle2D

<Match>
        <OR>
            <Class name="~.*\.MyPoint2D" />
            <Class name="~.*\.MyRectangle2D" />
        </OR>
        <Bug code="FE" />
        <Justification author="My Name" />
        <Justification
            text="Floating point equals works (here)." />
    </Match>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!