double d = -1; if (d==-1) { } 
  1. Under what circumstances does the comparison safety at == become low? It is necessary to multiply the variable, divide it or something, so that double starts to show the error like not 0 , but 0.00000001 , and you have to use epsilon, and not a simple comparison.
  2. In the compiler settings there is an option: Computing model with a floating point (exact, strict, fast) . What does it have to do if “ fast ” is set, will double not exactly work?
  • What is "security" in your understanding? Yes, it is safe to compare - the computer will not explode, and no one will withdraw money from your card. - Kromster

5 answers 5

I answer in points:

  1. It is impossible to compare two numbers with a floating point to each other, due to the fact that numbers with a floating point cannot be represented exactly, therefore we cannot rely on the comparison operator.

    Popular comparison practices are:

     #include <cmath> #include <limits> bool is_equal(double x, double y) { return std::fabs(x - y) < std::numeric_limits<double>::epsilon(); } 

    You can ask your "epsilon".

  2. As I understand it, it’s about MS VC ++. Compiler options are described here https://msdn.microsoft.com/ru-ru/library/e7s85ffb.aspx If you select fast, then the IEEE 754 standard will not be respected. Comparisons with Nan, etc. will not work.

    A comparison for strict equality is almost never safe. Instead, use fabs(xy) < EPS , where EPS is a constant, for example, 1e-7 .

    The only case where you can afford a strict comparison is if there is some constant that you could assign yourself (obviously, without calculations), and with which you compare in order to find out if there was a reassignment. And even in this place one has to be careful, because there are cases when, due to optimization, the compared values ​​have a different type, which leads to different accuracy and inequality.

    All the calculations with integers up to 2 53 are exact. It is used by languages ​​with a single numeric type (for example js). However, if you are sure that the value is an integer, then why bother to use double at all? It is better to take a 64-bit integer type.

      If you want to compare two double , it is best to use such a comparison (after the < sign, you indicate to which decimal place you are interested in the comparison):

       #include <cmath> double L, R; if( abs(LR) < 0.00001 ) 

      If the if done, your two double are equal.

      • How is this answer different from others? - Qwertiy
      • @Qwertiy I think that this method will be clearer to beginners, it does not use any functions - Alexey
      • So mine doesn't use either :) - Qwertiy

      This way of comparing floating-point numbers is suggested by the Qt developers:

       Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2))); } Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) { return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2))); } 

      Here Epsilon depends on the numbers themselves being compared. But what is better - I can not say.

        I do not know if my advice will be useful for you. When reading a point of a certain dependence from a file — given with a certain step (0.1) on the abscissa or with a random step, I usually, without prejudice to accuracy, try to express the abscissas using binary fractions (denominator = 2 ^ n). For example, 0.1 = ~ 51/512. And then, using interpolation, I change the abscissas and ordinates. Then comparisons ==, <and> become correct. Interpolation of data does not take much time and has almost no effect on accuracy.