Is it safe when compare 2 float/double directly in Java?

后端 未结 9 962
刺人心
刺人心 2020-12-17 02:30

Is it safe if I use comparision like this (a is int, b and c is float/double):

a == b
b == c

It may hear ridiculous, but in my old programi

相关标签:
9条回答
  • 2020-12-17 02:52

    In java you can compare a float with another float,and a double with another double.And you will get true when comparing a double with a float when their precision is equal

    0 讨论(0)
  • 2020-12-17 02:52

    b is float and 10 is integer then if you compare both with your this critearia then it will give false because...

    b = flaot (meance ans 3.33333333333333333333333)
    10 is integer so that make sence.
    
    0 讨论(0)
  • 2020-12-17 02:54

    If you want a more complete explanation, here there is a good one: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html (but it is a little bit long)

    0 讨论(0)
  • 2020-12-17 02:57

    The safest way to compare a float/double with something else is actually to use see if their difference is a small number.

    e.g.

    Math.abs(a - b) < EPS
    

    where EPS can be something like 0.0000001.

    In this way you make sure that precision errors do not affect your results.

    0 讨论(0)
  • 2020-12-17 02:59

    == comparison is not particularly safe for doubles/floats in basically any language. An epsilon comparison method (where you check that the difference between two floats is reasonably small) is your best bet.

    For:

    Math.sqrt(b) == Math.sqrt(c)
    

    I'm not sure why you wouldn't just compare b and c, but an epsilon comparison would work here too.

    For:

    b / 3 == 10 / 3
    

    Since 10/3 = 3 because of integer division, this will not necessarily give the results you're looking for. You could use 10.0 / 3, though i'm still not sure why you wouldn't just compare b and 10 (using the epsilon comparison method in either case).

    0 讨论(0)
  • 2020-12-17 03:11

    In general, no it is not safe due to the fact that so many decimal numbers cannot be precisely represented as float or double values. The often stated solution is test if the difference between the numbers is less than some "small" value (often denoted by a greek 'epsilon' character in the maths literature).

    However - you need to be a bit careful how you do the test. For instance, if you write:

    if (Math.abs(a - b) < 0.000001) {
        System.err.println("equal");
    }
    

    where a and b are supposed to be "the same", you are testing the absolute error. If you do this, you can get into trouble if a and b are (say_ 1,999,999.99 and 2,000,000.00 respectively. The difference between these two numbers is less than the smallest representable value at that scale for a float, and yet it is much bigger than our chosen epsilon.

    Arguably, a better approach is to use the relative error; e.g. coded (defensively) as

    if (a == b ||
        Math.abs(a - b) / Math.max(Math.abs(a), Math.abs(b)) < 0.000001) {
        System.err.println("close enough to be equal");
    }
    

    But even this is not the complete answer, because it does not take account of the way that certain calculations cause the errors to build up to unmanageable proportions. Take a look at this Wikipedia link for more details.

    The bottom line is that dealing with errors in floating point calculations is a lot more difficult than it appears at first glance.


    The other point to note is (as others have explained) integer arithmetic behaves very differently to floating point arithmetic in a couple of respects:

    • integer division will truncate if the result is not integral
    • integer addition subtraction and multiplication will overflow.

    Both of these happen without any warning, either at compile time or at runtime.

    0 讨论(0)
提交回复
热议问题