What is the proper way to compare equality of two variables that could be NaN?

111 Views Asked by At

I found a bug in the codebase I'm working in where they check for equality of two doubles (first, second) using first == second, but these 2 variables could be NaN.

If both variables were NaN the equality would be false.

So my current solution is instead of

first == second

we use

(first == second || (std::isnan(first) && std::isnan(second))

Is there a simpler way to do this?

2

There are 2 best solutions below

3
Silvio Mayolo On

First, evaluate that you actually want the condition to run if both values are NaN. NaN is a good indicator that things went terribly wrong, not a null or empty state. If the intention was to have two values that may or may not exist, you might consider changing them to std::optional<double> to make that clear. Otherwise, if you are certain, then what you've done is correct. There's no magic trick to making NaN comparisons work, and even if you did find a library that abstracted this away, it would still do exactly what you just did under the hood.

1
Martin York On

Rather than use an overly generic expression:

(first == second || (std::isnan(first) && std::isnan(second))

Use a named function to start with:

inline bool areFloatPointComparablyEquivelent(double lhs, double rhs)
{
      // Add a long very detailed explanation of why you need
      // This expression (in two years you will not be here and the
      // the next maintainer may own an axe and know where you live).

      // The exact reason or expression is not that important.
      // What is important (if not trivial, obvious) is a WHY.
      return result;
}

Now use this self documenting function wherever you need to do this test (even if it is only in one place).