30

I am going to do some math calculations using C++ . The input floating point number is a valid number, but after the calculations, the resulting value is NaN. I would like to trace the point where NaN value appears (possibly using GDB), instead of inserting a lot of isNan() into the code. But I found that even code like this will not trigger an exception when a NaN value appears.

double dirty = 0.0;
double nanvalue = 0.0/dirty;

Could anyone suggest a method for tracing the NaN or turning a NaN into an exception?

Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
user1492900
  • 575
  • 1
  • 8
  • 16
  • Related: [Can I make gcc tell me when a calculation results in NaN or inf at runtime?](http://stackoverflow.com/questions/2941611/can-i-make-gcc-tell-me-when-a-calculation-results-in-nan-or-inf-at-runtime/20973509) – legends2k May 02 '14 at 09:40
  • Also http://stackoverflow.com/questions/5393997/stopping-the-debugger-when-a-nan-floating-point-number-is-produced – Riot Oct 02 '15 at 15:34

4 Answers4

41

Since you mention using gdb, here's a solution that works with gcc -- you want the functions defined in fenv.h :

#define _GNU_SOURCE
#include <fenv.h>
#include <stdio.h>

int main(int argc, char **argv)
{
   double dirty = 0.0;

   feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);  // Enable all floating point exceptions but FE_INEXACT
   double nanval=0.0/dirty;
   printf("Succeeded! dirty=%lf, nanval=%lf\n",dirty,nanval);
}

Running the above program produces the output "Floating point exception". Without the call to feenableexcept, the "Succeeded!" message is printed.

If you were to write a signal handler for SIGFPE, that might be a good place to set a breakpoint and get the traceback you want. (Disclaimer: haven't tried it!)

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
  • 13
    Thanks for this answer, I just want to point out that enabling *all* the floating point exceptions enables also FE_INEXACT which happens very often (even for: float f = 0.1) and the debug becomes impossible. Is much better to use feenableexcept(FE_DIVBYZERO| FE_INVALID|FE_OVERFLOW); – DarioP Jul 15 '13 at 13:33
  • Here's a useful page for OS X, which doesn't include feenableexcept: http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c – charlie roberts Oct 18 '17 at 19:58
7

In Visual Studio you can use the _controlfp function to set the behavior of floating-point calculations (see http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx). Maybe there is a similar variant for your platform.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • Hi, thank you for your answer. Unfortunately my platform is GCC4.1 , Centos 5.5 Linux. I am still trying to figure out how to achieve the same thing in Linux with GCC – user1492900 Sep 01 '10 at 08:07
  • 3
    feenableexcept() seems working, I am now trying to trace my program with this. http://gcc.gnu.org/onlinedocs/gcc-3.1.1/g77/Floating-point-Exception-Handling.html#Floating-point%20Exception%20Handling – user1492900 Sep 01 '10 at 08:14
1

Some notes on floating point programming can be found on http://ds9a.nl/fp/ including the difference between 1/0 and 1.0/0 etc, and what a NaN is and how it acts.

0

One can enable so-called "signaling NaN". That should make it easily possible to make the debugger find the correct position.

Via google, I found this for enabling signaling NaNs in C++, no idea if it works:

std::numeric_limits::signaling_NaN();

Usefulness of signaling NaN?

Community
  • 1
  • 1
Uli Schlachter
  • 9,337
  • 1
  • 23
  • 39
  • 2
    That expression evaluates to a signaling NaN, but I think pagedown is more interested in forcing a floating point exception for operations that return NaN, which would probably be a platform-specific compiler option, or runtime configuration of the FP processor. – Jim Lewis Sep 01 '10 at 07:29
  • Ah sorry. I understood it as making all NaN signaling. – Uli Schlachter Sep 01 '10 at 07:40
  • Thank you very much. My platform is GCC4.1 , Centos 5.5 Linux I am going to take a look at the compiler options :) – user1492900 Sep 01 '10 at 08:00