0

Is it safe to use the '==' operator to determine if a double variable in C++ has changed since its initialization to 0.0?

For performance reasons I want to avoid re-calcuation of a value inside a nested for-loop if it has been already calculated.

If it is considered unsafe: Can this lead to false positives (i.e. the expression returns true although the value does not equal 0.0), false negatives (i.e. the expression returns false although the values is indeed 0.0) or both/undetermined behaviour?

I am using C++-14 and the GNU C++ compiler v5.4.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Calyx
  • 98
  • 1
  • 7
  • Very related: [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) In short, once you've done a few calculations, there very little chance a floating point value is *exactly* equal to something. – Some programmer dude Apr 14 '18 at 09:15
  • 1
    "*to determine if a double variable in C++ has changed since its initialization to 0.0?*" What if it is changed to `3.1416` and then set to `0.0` again? It has changed, but it is `==0.0`. – juanchopanza Apr 14 '18 at 09:27
  • Nevertheless, wouldn't it be very strange if an untouched variable changed simply because I used floating-point arithmetic somewhere in the mean-time? As far as I know, 0 has an exact float representation, so (0.0 == 0.0) is predictable as true. – Calyx Apr 14 '18 at 09:30
  • As a float/double is always an approximation, comparing one should be relative to a precission, e.g. `if (myDouble>-0.00001 && myDouble<0.00001)... // assume zero` – Paul Ogilvie Apr 14 '18 at 09:31
  • Even if 0 has an exact float representation, it does not mean that a cacluclation will yield this exact representation. – Paul Ogilvie Apr 14 '18 at 09:32
  • 2
    @Calyx Yes, `0.0` is one of the values that can be represented exactly, so the comparison is safe. But you can't conclude that something initialized to `0.0` has not been changed because sometime later it is `==0.0`. – juanchopanza Apr 14 '18 at 09:32
  • @juanchopanza Thanks. This is not an issue in my case, the question was not clear in this way. I hope the edit clarifies it. – Calyx Apr 14 '18 at 09:36
  • Note there are other magic values you can use, such as NAN. – juanchopanza Apr 14 '18 at 09:37
  • 1
    I use the trick of either initializing to `NAN` or to `-0.0` for this purpose. – Eljay Apr 14 '18 at 11:38

1 Answers1

3

In C++, the expression x == 0. evaluates to true if and only if x is zero.

The only senses in which you could have a false positive or false negative are:

  • x is the result of calculations that produced zero when the ideal exact mathematical result would be non-zero or vice-versa. In other words, the problem is that x does not contain the value you want, not that comparing with zero does not work properly.
  • Rather than a simple object x, the comparison uses a floating-point expression, as in x/y == 0.. C++ allows expressions to be evaluated with more precision than the nominal type. This excess precision is discarded when the value is assigned or converted by a cast. So the comparison could indicate the expression is non-zero even though assigning it to an object would produce zero in the object.
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312