Hacker News new | ask | show | jobs
by maximilianburke 1256 days ago
I think the concept of NaNs are sound, but I think relying on them is fraught with peril, made so by the unobvious test for NaN-ness in many languages (ie, "if (x != x)"), and the lure of people who want to turn on "fast math" optimizations which do things like assume NaNs aren't possible and then dead-code-eliminate everything that's guarded by an "x != x" test.

Really though, I'm a fan, I just think that we need better means for checking them in legacy languages and we need to entirely do away with "fast math" optimizations.

4 comments

I call them "buggy math" optimizations. The dmd D compiler does not have a switch to enable buggy math.
> made so by the unobvious test for NaN-ness in many languages (ie, "if (x != x)")

Which languages do not have a function to test for NaN?

> and the lure of people who want to turn on "fast math" optimizations which do things like assume NaNs aren't possible and then dead-code-eliminate everything that's guarded by an "x != x" test.

This is not unique to NaNs. There are plenty of potential floating point problems if you enable those flags.

> Which languages do not have a function to test for NaN?

Both C and C++.

> This is not unique to NaNs. There are plenty of potential floating point problems if you enable those flags.

That's why I said in the second part that we need to do away with them.

C has had isnan() for over two decades. It’s technically a macro, but that doesn’t matter for this use case.
> Both C and C++.

Seems C++ only added it in C++11. Surprising.

> That's why I said in the second part that we need to do away with them.

Do away entirely with fast math calculations? That would be horrible. They exist for a very good reason: Some applications are too slow without them. Enabling subnormal numbers can really slow things down.

I'd wager that for the majority of programs written, the fast math is as good as the accurate math.

> I'd wager that for the majority of programs written, the fast math is as good as the accurate math.

I'd take that wager. I spent 13 years working on video games and video game technology, a domain where floating point performance is critical, and by and large we never used fast-math because of the problems it created for us.

This is surprising to me! Can you explain what problems you encountered? My (limited) understanding is that the main effect of fast-math is to turn off support for subnormals. Since subnormals are only used to represent extremely small values, I wouldn't expect them to have much effect in the real world.
fast-math can result in many things you may not expect, e.g. treating FP operations as being associative and distributive, which they aren’t.
Happy to take that wager, because the majority of programs written are not video games related :-)
I’m more curious about how it caused problems for you if you ever used it
> Seems C++ only added it in C++11

I added it to Digital Mars C and C++ in the early 1990s. Also full NaN support in all the math.h functions. AFAIK it was the first C compiler to do it.

It was based on a specification worked out by NCEG (Numerical C Extensions Group), a long forgotten group that tried to modernize C numerics support.

> the fast math is as good as the accurate math

I was more interested in correct results than fast wrong answers.

Yes, but for most C++ applications, they prefer the faster wrong answers, because the wrong answers are not wrong enough to cause any bugs.
> Some applications are too slow without them.

I fully expect the intersection between programs where floating point instructions are a speed bottleneck and programs where the numerical instability that fast_math can cause is not a problem is the empty set.

IIRC we used -ffast-math for numerical simulations of radar cross sections. Fast math was a decent perf win but didn't have any negative effects on the results.

Most programs don't care about the difference between ((a+b)+c) vs (a+(b+c)). Why bother with NaNs if you know you can't get them? Etc.

Something akin to fast-math is the default for some shading languages (although some have switched to fast-math-but-preserve-NaN-and-INF).
isnan() has been around since C99.
isnan is a macro, not a function
isnan is a macro in C, function in C++. But either way, it’s an abstraction that provides a standard test for NaNs in those languages.
I believe the reason he is pointing out this distinction is that if it is a macro, it can be optimized out causing bugs.
NaNs are incredibly helpful in numpy. Often I want to take a mean over a collection of lists but the size of each list isn't constant. Np.nanmean works great.
> I think the concept of NaNs are sound, but I think relying on them is fraught with peril

Well, allegedly in D at least https://www.reddit.com/r/rust/comments/a1w75c/the_bug_i_did_...