We all know that it is impossible (more precisely not recommended) to use the float == operation. Why - I think you know. But what about comparing with 0? That is, let's say, we have some kind of variable, initialized by zero during creation, and further, it is possible that some value will be assigned to it, and it may not be. Accordingly, if the value of the variable is zero, then it has not been initialized. Since during initialization by zero all bits in the variable will be set to 0, I see no reason why not to compare the float (in this case) with zero. Is it so?

  • one
    By and large, comparison for equality with the initializer can be applied (the value has been changed or not) for any value, so long as the initializer itself looks exactly the same :) - in the sense that the bit representation will be the same. - Harry
  • Then Nan be used, not 0 . Or altogether std::optional , if you want to distinguish the presence of a value. - αλεχολυτ

2 answers 2

If it is known that the number is represented exactly, namely:

  1. There is no computational error.
  2. The constant itself is representable in the appropriate type without error.

then you can compare to equality.

In other cases, the comparison is undesirable and may lead to incorrect results.

    It is not recommended to compare the calculated float for equality with zero.

    It is not recommended to compare any float, neither computed nor constant for equality with zero (and for the equality of the two floats among themselves).
    For a constant float, the comparison will work correctly, but this is not a general case.

    Suppose there is a code.

     float n=0; float a1; float a2; //здесь a1 и a2 получили какие-то значения, //возможно пришедшие из внешнего мира (например считанные с АЦП) float delta=a1-a2; if(delta==n){ //do something1 } else{ //do something2 } 

    When the difference is calculated, delta a1 and a2 can be equal to the accuracy of the float type.
    But the difference is not equal to zero and, accordingly, the comparison for equality to zero will not work.
    And the algorithm will go on another branch.

    As delta, it can be not a simple difference, but arbitrarily complex calculations.
    In which there will be rounding errors that will give + -1 to float accuracy.

    Therefore not recommended.


    For two constants, of course, this will work.
    And for non-zero constants, it will also work (on the same platform, of course).

    For example:

     float n1=0; float n2=0; if(n1==n2){ //do something1 } else{ //do something2 } 

    Or an example for non-zero constants:

     float n1=1.1; float n2=1.1; if(n1==n2){ //do something1 } else{ //do something2 } 

    But in general, when a float is obtained after a calculation, at the end the float will have + -1 float precision.
    And maybe more than + -1 float accuracy.

    UPD1:

    And what is the "+ -1 accuracy of float" is some kind of non-generic term

    Something I do not remember what is the generally accepted term for this.
    Maybe "machine epsilon" is the term for this, that is, the FLT_EPSILON constant from float.h.
    Or maybe FLT_MIN is the term for that.
    Probably still FLT_EPSILON.

    UPD2:

    A possible comparison subroutine for equality for float (if you make a pattern out of it, then it is suitable for other floating point formats):

     bool compare_fl_point(float a1, float a2, float delta=FLT_EPSILON){ float delta1=a1-a2; if(delta1<0) delta1=-delta1; if(delta1>delta) return false; else return true; } 

    As the delta parameter, it is necessary to choose the accuracy of the calculations in this task, taking into account the accuracy of the source data and the accuracy of the actual calculations on this platform.
    It is usually recommended that the accuracy of the actual calculations on this platform exceed the accuracy of the input data by at least an order of magnitude.

    UPD3:

    EPSILON works a little differently - Kromster 1 hour ago

    Epsilon is here for example only as a default value.
    Moreover, to compare with epsilon is meaningless, since epsilon is (by definition) always less than or equal to any float number.
    At the site of the epsilon there should be an accuracy of the input data in this particular problem.
    Typically, the accuracy of the calculations is chosen so that it is at least 10 times higher than the accuracy of the input data.

    UPD4:

    In general, you need to google this question.
    There can be no two opinions, there are rules written by the developers of the standard for float.
    It unequivocally says how to compare float to equality.
    I googled, but immediately fell just the same irresponsible bazaars of developers on the forums, as here.
    There should be a standard in which all this is spelled out.
    You can still try to look at Knut, maybe he has.

    UPD5:

    But I found something similar to an article on the topic:

    https://habr.com/post/112953/

    There is also a comparison about float for equality.
    And even a reference to some import article.

    UPD6:

    I decided to conduct a computational experiment to see how round-off float errors appear.
    To do this, wrote a program that verifies the known identity sin (x) ^ 2 + cos (x) ^ 2 = 1;

    Here is the program:

     // Example program #include <iostream> #include <string> #include <cmath> using namespace std; const int numpoint=10; int main(){ int i; for(i=0;i!=numpoint;++i){ float arg=3.14/((float)i+1.0); float s=sin(arg); float c=cos(arg); float one=s*s+c*c; float delta=one-1.0; bool flag; if(delta==0.0) flag=true; else flag=false; cout<<endl<<i<<". delta="<<delta<<" flag="<<flag<<" arg="<<arg; } return 0; } 

    The result of the program:

     0. delta=0 flag=1 arg=3.14 1. delta=0 flag=1 arg=1.57 2. delta=0 flag=1 arg=1.04667 3. delta=0 flag=1 arg=0.785 4. delta=0 flag=1 arg=0.628 5. delta=0 flag=1 arg=0.523333 6. delta=-5.96046e-08 flag=0 arg=0.448571 7. delta=-5.96046e-08 flag=0 arg=0.3925 8. delta=-5.96046e-08 flag=0 arg=0.348889 9. delta=-5.96046e-08 flag=0 arg=0.314 

    It can be seen that for some arguments there is a delta that does not equal zero and the comparison operator delta with zero

     if(delta==0.0) flag=true; else flag=false; 

    returns false.

    All this was checked on http://cpp.sh/

    • one
      Corrected the statement above. And what is the "+ -1 accuracy of float" is some kind of non - generally accepted term - Kromster
    • EPSILON works a little differently - Kromster