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 05:16

I think there is a lot of confusion around floats (and doubles), it is good to clear it up.

  1. There is nothing inherently wrong in using floats as IDs in standard-compliant JVM [*]. If you simply set the float ID to x, do nothing with it (i.e. no arithmetics) and later test for y == x, you'll be fine. Also there is nothing wrong in using them as keys in a HashMap. What you cannot do is assume equalities like x == (x - y) + y, etc. This being said, people usually use integer types as IDs, and you can observe that most people here are put off by this code, so for practical reasons, it is better to adhere to conventions. Note that there are as many different double values as there are long values, so you gain nothing by using double. Also, generating "next available ID" can be tricky with doubles and requires some knowledge of the floating-point arithmetic. Not worth the trouble.

  2. On the other hand, relying on numerical equality of the results of two mathematically equivalent computations is risky. This is because of the rounding errors and loss of precision when converting from decimal to binary representation. This has been discussed to death on SO.

[*] When I said "standard-compliant JVM" I wanted to exclude certain brain-damaged JVM implementations. See this.

查看更多
心情的温度
3楼-- · 2018-12-31 05:16

As mentioned in other answers, doubles can have small deviations. And you could write your own method to compare them using an "acceptable" deviation. However ...

There is an apache class for comparing doubles: org.apache.commons.math3.util.Precision

It contains some interesting constants: SAFE_MIN and EPSILON, which are the maximum possible deviations of simple arithmetic operations.

It also provides the necessary methods to compare, equal or round doubles. (using ulps or absolute deviation)

查看更多
倾城一夜雪
4楼-- · 2018-12-31 05:16

The correct way would be

java.lang.Float.compare(float1, float2)
查看更多
登录 后发表回答