DEV Community

Soma
Soma

Posted on

Right way to compare double and float in Java?

If you have been doing Java programming then you may know that the use of == operator is not the correct way to compare floating point values in Java. If you use equality operator to compare float and double variables then it can cause an endless loop in Java, but is there a way to prevent that loop from running infinitely? Yes, instead of using == operator, you can use relational operator e.g. less than (<) or greater than (>) to compare float and double values.

By changing the above code as following, you can prevent the loop from infinitely  :

for(double balance = 10; balance > 0; balance-=0.1) {\
   System.out.println(balance);\
}
Enter fullscreen mode Exit fullscreen mode

If you think little bit than you will realize that greater than will definitely end this loop, but don't expect it to print numbers like 9.9, 9.8, 9.7 because floating point numbers are just approximation, they are not exact. Some numbers e.g. 1/3 cannot be represented exactly using float and double in Java.

After running following program in your computer you may end up with something like this

Java Program  to compare float and double values:

Here is the complete Java program to check if two float or double values are equal, greater or less than of each other.

public class FloatComparator {

    public static void main(String args[]){
        float firstValue = 10.2f;
        float secondValue = 10.3f;
        float thirdValue = 10.2f;

        if(firstValue > secondValue){
            System.out.print("First Value and second value are not equal");
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

 
By the way, this is not the only way, you can also use equals() method of Wrapper classes like Float and Double to do the floating point comparison. They are in fact preferred way if you want to check if two floating point values are equal or not but if you just want to know that they are not equal then using < and > operator is rather easy.

That's all about right way to compare float and double values in loop in Java. This simple trick of using logical operator less than and greater than instead of equality operator to compare float and double variable can save you a lot of headache.

Top comments (2)

Collapse
 
cicirello profile image
Vincent A. Cicirello • Edited

You are correct that using == to compare floating-point numbers in Java is almost always problematic. However, you mistakenly suggest using the equals method of the wrapper classes Double or Float as an alternative. That has the same issue. If the floating-point values you are comparing are the results of calculations, there is risk of rounding errors causing values that should be considered equal to be different. The equals method of the wrapper classes just compare the wrapped primitive values with == so it has the same issue.

Your suggestion of using < or > is appropriate in many cases such as your loop example. But not so much in others. Even in that example, due to potential of rounding error in the decrement by 0.1, it is not entirely clear without running whether the last iteration will give you something around 0.1 or around 0.0 such as 0.000000000000002. It depends on which side of 0.0 the last result lies.

In other cases you may need to know if 2 doubles are sufficiently equal. The > doesn't help at all. If condition is false, it doesn't mean they are equal.

Here is how to actually compare 2 floating-point values for "equality":

public boolean approximatelyEqual(double a, double b, double epsilon) {
  return Math.abs(a - b) < epsilon;
}
Enter fullscreen mode Exit fullscreen mode

You then use a small value for epsilon. How small depends on situation. 1E-10 should be fine in many cases. So you can use the above like:

double a = computeA();
double b = computeB();
if (approximatelyEqual(a, b, 1E-10)) {
  doEqualCaseThing();
} else {
  doUnequalCaseThing();
}
Enter fullscreen mode Exit fullscreen mode

Going back to your loop example, you can fix the issue of which iteration is actually last using a similar trick.

If you want to exclude the approximately 0 case, then do:

for (double balance = 10; balance > 1E-5; balance -= 0.1) {
   System.out.println(balance);
}
Enter fullscreen mode Exit fullscreen mode

I used a larger epsilon this time based on the scale of your numbers. We also don't need the Math.abs this time. You'll need to modify this a bit if you want to include the approximately 0 case.

Collapse
 
somadevtoo profile image
Soma

Thanks, looks like still a lot to learn :-)