Friday, September 27, 2013

How to compare float numbers safely?

This short article explains why we cannot use "==" to compare floats and how to compare floats right.
You can try to run this code in Java to understand the problem. double a = 1.0f / 3.0f;
double b = a + a + a;

System.out.println(a); // Output 0.3333333432674408
System.out.println(b); // Output 1.0000000298023224
System.out.println(1 == b); // Output false

Why?

If the compared values are the results of computation, they can be not equal.
Binary representation of the number 1/3 cannot be precise, because the place where the number is stored is limited. So the number rounding was made: 1/3 = 0.333.. = 0.(3) = 0.3333333432674408
So we have b = 1.0000000298023224 that is not equal to 1.0;

How to get round that problem?

We have to choose a tolerance level to compare float numbers. For example,
final float TOLERANCE = 0.00001f;

double a = 1.0f / 3.0f;
double b = a + a + a;

System.out.println(a); // Output 0.3333333432674408
System.out.println(b); // Output 1.0000000298023224
System.out.println(Math.abs(1 - b) < TOLERANCE); // Output true
Don't miss Math.abs. You cannot be sure the result of (1 - b) is positive.

I have one more trick for you.
double num = 1.0;
while (num != 0.0)
     num = num - 0.1;
Don't repeat at home. We've got the infinite loop here!
Now you know the reason. num will never have a value exactly equal to 0.0