What's wrong with using == to compare floats i

2018-12-31 04:15发布

According to this java.sun page == is the equality comparison operator for floating point numbers in Java.

However, when I type this code:

if(sectionID == currentSectionID)

into my editor and run static analysis, I get: "JAVA0078 Floating point values compared with =="

What is wrong with using == to compare floating point values? What is the correct way to do it? 

21条回答
流年柔荑漫光年
2楼-- · 2018-12-31 04:59

Foating point values are not reliable, due to roundoff error.

As such they should probably not be used for as key values, such as sectionID. Use integers instead, or long if int doesn't contain enough possible values.

查看更多
闭嘴吧你
3楼-- · 2018-12-31 04:59

The following automatically uses the best precision:

/**
 * Compare to floats for (almost) equality. Will check whether they are
 * at most 5 ULP apart.
 */
public static boolean isFloatingEqual(float v1, float v2) {
    if (v1 == v2)
        return true;
    float absoluteDifference = Math.abs(v1 - v2);
    float maxUlp = Math.max(Math.ulp(v1), Math.ulp(v2));
    return absoluteDifference < 5 * maxUlp;
}

Of course, you might choose more or less than 5 ULPs (‘unit in the last place’).

If you’re into the Apache Commons library, the Precision class has compareTo() and equals() with both epsilon and ULP.

查看更多
唯独是你
4楼-- · 2018-12-31 04:59

If you *have to* use floats, strictfp keyword may be useful.

http://en.wikipedia.org/wiki/strictfp

查看更多
心情的温度
5楼-- · 2018-12-31 04:59

In one line answer I can say, you should use:

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)

To make you learned more about using related operators correctly, I am elaborating some cases here: Generally, there are three ways to test strings in Java. You can use ==, .equals (), or Objects.equals ().

How are they different? == tests for the reference quality in strings meaning finding out whether the two objects are the same. On the other hand, .equals () tests whether the two strings are of equal value logically. Finally, Objects.equals () tests for any nulls in the two strings then determine whether to call .equals ().

Ideal operator to use

Well this has been subject to lots of debates because each of the three operators have their unique set of strengths and weaknesses. Example, == is often a preferred option when comparing object reference, but there are cases where it may seem to compare string values as well.

However, what you get is a falls value because Java creates an illusion that you are comparing values but in the real sense you are not. Consider the two cases below:

Case 1:

String a="Test";
String b="Test";
if(a==b) ===> true

Case 2:

String nullString1 = null;
String nullString2 = null;
//evaluates to true
nullString1 == nullString2;
//throws an exception
nullString1.equals(nullString2);

So, it’s way better to use each operator when testing the specific attribute it’s designed for. But in almost all cases, Objects.equals () is a more universal operator thus experience web developers opt for it.

Here you can get more details: http://fluentthemes.com/use-compare-strings-java/

查看更多
永恒的永恒
6楼-- · 2018-12-31 05:01

In addition to previous answers, you should be aware that there are strange behaviours associated with -0.0f and +0.0f (they are == but not equals) and Float.NaN (it is equals but not ==) (hope I've got that right - argh, don't do it!).

Edit: Let's check!

import static java.lang.Float.NaN;
public class Fl {
    public static void main(String[] args) {
        System.err.println(          -0.0f   ==              0.0f);   // true
        System.err.println(new Float(-0.0f).equals(new Float(0.0f))); // false
        System.err.println(            NaN   ==               NaN);   // false
        System.err.println(new Float(  NaN).equals(new Float( NaN))); // true
    }
} 

Welcome to IEEE/754.

查看更多
旧人旧事旧时光
7楼-- · 2018-12-31 05:01

You can use Float.floatToIntBits().

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)
查看更多
登录 后发表回答