Comparing FLOAT/DOUBLE values (in ANY programming language)

  1. Calculations involving float and double values are inexact (uses approximate values)

          double r = Math.sqrt(2.0);
    
          if ( r * r == 2.0 )       
             System.out.println("r is equal the square root of 2");
          else
             System.out.println("r is NOT equal the square root of 2");
    

    Question: what do you think it will print ?

    Check out the DEMO program: click here

  2. Programming commandment:

    (Because == and != test if two values are exactly equal or exactly not equal.)

  3. A better test for equality for float and double values is:

    A better test for "x == y" for float/double values is:
          Math.abs(x - y) < EPSILON  (a small value, like 0.0000001)
    

  4. This test is still not good enough:

    Example: x = 99999999999999999.0 and y = 99999999999999998.0
          Math.abs(x - y) = 1.0
          Math.abs(x - y) < 0.0000001             FAILS
    

    Example: x = 0.99999999999999999 and y = 0.99999999999999998
          Math.abs(x - y) = 0.00000000000000001
          Math.abs(x - y) < 0.0000001             PASSES
    

    Note that: x is "just as equal to" y in both cases
    (if x == y, then 10*x == 10*y, 100*x == 100*y, and so on...)

  5. Testing equality for float/double values:

    Always use the following test to check is x == y (float/double):
          Math.abs(x - y) < EPSILON * Math.max( Math.abs(x), Math.abs(y) )
    

  6. This test will work for the examples above:

    Example: x = 99999999999999999.0 and y = 99999999999999998.0
          Math.abs(x - y) = 1.0
          Math.max( Math.abs(x), Math.abs(y) ) = 99999999999999999.0
    
          Math.abs(x - y) < EPSILON * Math.max( Math.abs(x), Math.abs(y) )
     -->  1.0 < 0.0000001 * 99999999999999999.0       PASSES
    

    Example: x = 0.99999999999999999 and y = 0.99999999999999998
          Math.abs(x - y) = 0.00000000000000001
          Math.max( Math.abs(x), Math.abs(y) ) = 0.99999999999999999
    
          Math.abs(x - y) < EPSILON * Math.max( Math.abs(x), Math.abs(y) )
     -->  0.00000000000000001 < 0.0000001 * 0.99999999999999999   PASSES