views:

144

answers:

3

Hello all,

It is often hard to find the origin of a NaN, since it can happen at any step of a computation and propagate itself. So is it possible to make a C++ program halt when a computation returns NaN or inf? The best in my opinion would be to have a crash with a nice error message:

Foo: NaN encoutered at Foo.c:624

Is something like this possible? Do you have a better solution? How do you debug NaN problems?

EDIT: Precisions: I'm working with GCC under Linux.

A: 

I'm no C expert, but I expect the answer is no.

  1. This would require every float calculation to have this check. A huge performance impact.
  2. NaN and Inf aren't evil. They may be legitimately used in some library your app uses, and break it.
Bart van Heukelom
1. I believe the CPU raises a flag when that happens. Since it is done in hardware, there shouldn't be a big performance impact2. Sure, but for some applications they are :)
static_rtti
Regarding 1., it's done in hardware at no additional cost. 2. is a problem, but then again, simply changing the default round-to-even rounding mode to a directed one to implement interval arithmetic has this problem, so it's nothing new.
Pascal Cuoq
+1  A: 

Yes! Set (perhaps more or less portably) your IEEE 754-compliant processor to generate an interrupt when a NaN or infinite is encountered.

I googled and found these slides, which are a start. The slide on page 5 summarizes all the information you need.

Pascal Cuoq
+3  A: 

You can't do it in a completely portable way, but many platforms provide C APIs that allow you to access the floating point status control register(s).

Specifically, you want to unmask the overflow and invalid floating-point exceptions, which will cause the processor to signal an exception when arithmetic in your program produces a NaN or infinity result.

On your linux system this should do the trick:

#include <fenv.h> 
...
feenableexcept(FE_INVALID | FE_OVERFLOW);

You may want to learn to write a trap handler so that you can print a diagnostic message or otherwise continue execution when one of these exceptions is signaled.

Stephen Canon
Awesome! Thanks!
static_rtti