7

I know there are plenty of pitfalls with using the equal comparator with double's so I'm cautious on how to implement a check for a value equal to exactly 0.0. Basically, I want to know if a value was never assigned or if it was intentionally assigned the value 0.0 with a literal. I do not want to know if it is nearly zero (ex - 0.0000000001).

So I'm debating between using val == 0.0 or something like so:

bool isZero(double val)
{
    if (val > std::numeric_limits<double>::min()) {
        return false;
    } else if (val < -std::numeric_limits<double>::min()) {
        return false;
    }
    return true;
}

Would there be any difference between these two statements? Should I favor one over the other? I'm particularly concerned with the underflow scenario where val == -0.0.

Thanks


I should have clarified the 'never assigned' statement to 'never assigned after default initialization'.

DrTarr
  • 922
  • 2
  • 15
  • 34
  • 4
    1) Consider also `std::fpclassify(val) == FP_ZERO`. 2) Be careful with NaNs. Your `isZero` returns `true` for a NaN. – Evg Sep 21 '20 at 11:52
  • Also take care about the "never assigned" thing... Uninitialized local variables will have *indeterminate* values, and using such values (in *any* way) leads to undefined behavior. – Some programmer dude Sep 21 '20 at 11:57
  • 1
    Why are you concerned about `-0.0`? It's a valid zero, just like `0.0`. It's not only a result of underflow, e.g. `-1.0*0.0 == -0.0`. – rustyx Sep 21 '20 at 12:05
  • 2
    There is no way to tell whether a `double` was initialized or not, and there is no way to tell whether an initializer was a literal or some other expression. – molbdnilo Sep 21 '20 at 12:08
  • related: https://stackoverflow.com/questions/39108471/is-it-ok-to-compare-floating-points-to-0-0-without-epsilon – 463035818_is_not_an_ai Sep 21 '20 at 12:30
  • 1
    == does exactly what you think it does. The reason people tell you not to use == is because *usually* you *do* want to know if something is nearly zero. – user253751 Sep 21 '20 at 13:01
  • `std::numeric_limits::min()` is the smallest normalized number. You could have subnormal numbers (also called denormalized) that are not 0 but are smaller than `std::numeric_limits::min()`. – Eljay Sep 21 '20 at 13:01

1 Answers1

4

If you need to know if a floating point variable is exactly 0.0 or -0.0 then there is nothing wrong with using val == 0.0.

If you need to know if it is exactly 0.0 and not -0.0 then you must verify that you are using ieee-754 floating points and check whether the bit representation is all zero.

Mestkon
  • 3,532
  • 7
  • 18