Two floats are never equal

While we are on the topic of floating point fundamentals, there is another thing to remember: it is always a mistake to compare two floating-point numbers for equality.

It all boils down to the simple fact that floating-point arithmetic is not exact. It is meant for approximate calculations with engineering or scientific measurements, which are inexact to begin with. In fact, floating-point arithmetics results are almost never equal to the “true” value you would get by using exact real arithmetic.

Therefore, wherever you see something like x == 0.0, you can be fairly sure that it’s a mistake. Whatever computation produces the value of x, it’s unlikely to ever produce exactly 0.0.

The proper way to compare floating points is equality within some tolerance. For instance:

boolean approximatelyEqual(double a, double b, double epsilon) {
  return Math.abs(a - b) <= epsilon;
}

The above code works for most applications. It does not take into account the case that the inputs are NaN or infinities. I’m no expert of floating point arithmetic, so I will not give advice about this. For reference I copy here the following code from JUnit:

static public void assertEquals(String message, double expected,
    double actual, double delta) {
  if (Double.compare(expected, actual) == 0)
    return;
  if (!(Math.abs(expected - actual) <= delta))
    failNotEquals(message, new Double(expected), new Double(actual));
}  

The purpose of the compare call is to have the test pass when the two numbers are both NaN.

Leave a Reply