Live data from Hacker News

NaNs Just Don't Get No Respect

drdobbs.com

1–10 of 36 posts

Re: NaNs Just Don't Get No Respect

#3
NaNs are annoying because, thanks to them, equality on floating point numbers is not an equivalence relation. In particular, NaN /= NaN.

This means that in Haskell, for example, you cannot really rely on the Eq class representing an equivalence relation. Code relying on the fact that x == x should be true for all x could not work as expected for floating point numbers.

I don't know if this has any practical ramifications in real code, but it certainly makes things less elegant and more complex than they have to be.

Re: NaNs Just Don't Get No Respect

#4
post #3

NaNs are annoying because, thanks to them, equality on floating point numbers is not an equivalence relation. In particular, NaN /= NaN. This means that in Haskell, for example, you cannot really rely on the Eq class representing an equivalence relation. Code relying on the fact that x == x should be true for all x could not work as expected for floating point numbers. I don't know if this has any practical ramificat…

This looks very much like NULLs in the SQL world.

A null (and NaN) is like an unknown. One can't compare unknowns because they are exactly that, unknown.

Let's construct a language that on division on zero returns unknowns.

   a =  5 / 0;
   b = 10 / 0;
Now, both a and b are set to unknown state. If one were to compare a to b, should the expectation be that they hold same value?

I wish all languages would have nullability like SQL does. Where a great care has to be given to deal with nullable data, lest nulls nullify everything.

Re: NaNs Just Don't Get No Respect

#5
I've gotten a bit pissed at the Microsoft C compiler for (1) having no standard way to generate NaN or Infinity and (2) having a good enough static analyzer that if you generate one by casting, it emits a warning saying that your arithmetic overflows.

Gee, thanks MSC. I didn't expect "x = INFINITY;" to overflow.

Re: NaNs Just Don't Get No Respect

#6
An alternative workaround to writing `float f = 0` in languages without NaN:

    float f;
    bool thingIsFoo = condition1; // store the result…
    if (thingIsFoo)
        f = 7;
    // ... code ...
    if (thingIsFoo && condition2) // and explicitly depend on it later
        ++f;
But this causes an extra `&&` to be computed at runtime, so it seems NaNs are still better for this case.

Re: NaNs Just Don't Get No Respect

#7
post #3

NaNs are annoying because, thanks to them, equality on floating point numbers is not an equivalence relation. In particular, NaN /= NaN. This means that in Haskell, for example, you cannot really rely on the Eq class representing an equivalence relation. Code relying on the fact that x == x should be true for all x could not work as expected for floating point numbers. I don't know if this has any practical ramificat…

Would you prefer NaN be another type, like Maybe? And have to all math in a monad or with chronically repeated case analysis?It's necessary complexity, whichever way you do it.

Re: NaNs Just Don't Get No Respect

#8
post #7
post #3

NaNs are annoying because, thanks to them, equality on floating point numbers is not an equivalence relation. In particular, NaN /= NaN. This means that in Haskell, for example, you cannot really rely on the Eq class representing an equivalence relation. Code relying on the fact that x == x should be true for all x could not work as expected for floating point numbers. I don't know if this has any practical ramificat…

Would you prefer NaN be another type, like Maybe? And have to all math in a monad or with chronically repeated case analysis?It's necessary complexity, whichever way you do it.

Oh, I don't really have a good solution in mind--it's just annoying.

I guess one option would be to just declare that all NaNs are equal--I'm pretty sure that's how bottoms work in Haskell, and it seems that NaN is essentially a floating-point version of bottom.

Re: NaNs Just Don't Get No Respect

#10
post #3

NaNs are annoying because, thanks to them, equality on floating point numbers is not an equivalence relation. In particular, NaN /= NaN. This means that in Haskell, for example, you cannot really rely on the Eq class representing an equivalence relation. Code relying on the fact that x == x should be true for all x could not work as expected for floating point numbers. I don't know if this has any practical ramificat…

Attmepting to just use simple equivalence with any floating point type a horrible idea to begin with, even without NaNs. You should instead declare equivalence if the absolute difference between the two numbers is less than some bound based on what you're doing and not look for bit equivalency.

However, you should be able to examine two NaNs and declare them "equivalent" (for certain definitions of equivalence) by intelligently examining the bits based on the hardware that you're running the program on. In the case of a binary Nan [1] that would entail checking that the exponential fields are both entirely high (eg 0x8 == (a.exponent & b.exponent), assuming a standard 8 bit exponent) and that the mantissas are nonzero (eg a.mantissa && b.mantissa).

[1]: "Binary format NaNs are represented with the exponential field filled with ones (like infinity values), and some non-zero number in the significand (to make them distinct from infinity values)." --http://en.wikipedia.org/wiki/NaN

Post reply on HN