Is checking a double for equality ever safe?

前端 未结 5 1187
时光说笑
时光说笑 2020-12-03 04:42

I have the following code:

double x = 0;

{ ...do stuff ...}

if(x == 0){

}

I was always taught that you shouldn\'t check floats for equal

相关标签:
5条回答
  • 2020-12-03 05:08

    You still shouldn't check to see if it's equal to zero. Just check to see if it's near zero.

    private final static double EPSILON = 0.00001;
    if (x + EPSILON > 0 && x - EPSILON < 0){
    ...
    }
    
    0 讨论(0)
  • 2020-12-03 05:18

    It is safe if the 0 you're trying to catch is the original 0 set at initialization. However, it isn't safe if you're expecting a 0 from a mathematical operation.

    0 讨论(0)
  • 2020-12-03 05:24

    double has positive and negative zero. == between positive zero and negative zero returns false. Also, == betwen two NaNs returns false.

    0 讨论(0)
  • 2020-12-03 05:26

    The reason you shouldn't check floats for equality is that floating point numbers are not perfectly precise -- there's some inaccuracy in storage with some numbers, such as those that extended too far into the mantissa and repeating decimals (note that I'm talking about repeating decimals in base 2). You can think of this imprecision as "rounding down". The digits that extend beyond the precision of the floating-point number are truncated, effectively rounding down.

    If it has not changed, it will keep that equality. However, if you change it even slightly, you probably should not use equalities, but instead a range like (x < 0.0001 && x > -.0001).

    In short: as long as you're not playing with x at a very small level, it's OK.

    0 讨论(0)
  • 2020-12-03 05:33

    if you set it yourself and wish to see if it ever changed you can safely check for equality (like using a sentinel value) though NaN is safer for things like that

    float x=Float.NaN;
    {
       //some code that may or may not set x
    }
    if(Float.isNaN(x))//it never got set
    
    0 讨论(0)
提交回复
热议问题