Comparing floating point numbers in Java

16,578

Solution 1

Math.ulp() method has a practical use in testing. As you undoubtedly know, you should usually not compare floating-point numbers for exact equality. Instead, you check that they are equal within a certain tolerance. For example, in JUnit you compare expected to actual floating-point values like so:

assertEquals(expectedValue, actualValue, 0.02);

This asserts that the actual value is within 0.02 of the expected value. However is 0.02 a reasonable tolerance? If the expected value is 10.5 or -107.82, then 0.02 is probably fine. However, if the expected value is several billion, then the 0.02 may be completely indistinguishable from zero. Often what you should test is the relative error in terms of ULPs. Depending on how much accuracy the calculation requires, you usually select a tolerance somewhere between 1 and 10 ULPs. For example, here I specify that the actual result needs to be within 5 ULPs of the true value:

assertEquals(expectedValue, actualValue, 5*Math.ulp(expectedValue));

http://www.ibm.com/developerworks/java/library/j-math2/index.html

Solution 2

Yes, it's advisable to use a tolerance to check the absolute value of the difference between two floating point numbers.

Compare tells you if one double is less than, equal to, or greater than another. It won't tell you how close they are to one another, so, no, it's no safer than comparing with ==.

Share:
16,578
Klems
Author by

Klems

Updated on June 08, 2022

Comments

  • Klems
    Klems almost 2 years

    Possible Duplicate:
    Manipulating and comparing floating points in java

    Am I supposed to use an Epsilon while comparing floating point numbers in Java ? Does the Float.compare(float f1, float f2) static method is safe to use ?

    Thanks !

    EDIT : I think I got it.

    When I write, let's say, 3.6f in eclipse, the compilator interpret this number as 3.6. However, when I write 1.2f * 3.0f, the result is 3.6000001. While mathematically this is false, these two results are obviously inequals. Hence the need to have an epsilon while checking equality.

    However, when I write 0.0f in eclipse, the compilator interpret this as 0 strictly, because IEEE 754 is able to handle it correctly. Therefore, ensuring a float is strictly positive with (value > 0.0f) is correct.

    The only problem I see is when the computer doesn't use IEEE 754 representation, and instead use a representation which doesn't handle 0 correctly.

    Am I right ?

  • aioobe
    aioobe almost 13 years
    +1, revert my edit if you don't like it ;-)
  • Winter
    Winter almost 7 years
    What if one value is big and the other small ? Is taking the ULP of the sum a good idea ?