10

To find the cause of floating point variables beeing set to NaN in my C++ program I enabled floating point exceptions like this:

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

I know it works because when I write:

int val = 0.0/0.0;

in my program a floating point exception is risen. But NaNs are "spreading" through the floating point calculations of my program and I have no idea which variable is set to NaN first.

What causes for a variable beeing set to NaN exist, that would not cause a floating point exception?

Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
Nathan
  • 7,099
  • 14
  • 61
  • 125
  • When adding **FE_UNDERFLOW** I get lots of exceptions where I am multiplying by 0. Can an underflow really cause a NaN? – Nathan Mar 22 '11 at 16:45
  • 2
    @Nathan Are you sure you aren't actually multiplying by a very small number close to zero? – Mark B Mar 22 '11 at 16:47
  • @Nathan: As far as I read it, yes. Have a look at http://en.wikipedia.org/wiki/IEEE_754-2008 – Erik Mar 22 '11 at 16:49
  • 2
    @Nathan: An alternate way of tracking this down would be to make an `isNaN` function and start littering your code with `assert(!isNaN(x))` – Erik Mar 22 '11 at 16:51
  • @Nathan @Erik Just to be explicit, here's how you can write isNaN: template bool isNaN(T value) { return value != value; } – SuperElectric Mar 22 '11 at 18:18
  • @Erik. Looking on [link](http://en.wikipedia.org/wiki/IEEE_754-2008) the only thing about underflow is this: _a result is very small (outside the normal range)_ and is inexact. That does not cause a NaN, does it? Am I missing something? – Nathan Mar 22 '11 at 18:43
  • @Erik, @SuperEletric Yes, littering with isNaN tests is a possibility. That's what I am doing so far. It is very annoying that is why I am searching for an alternative. – Nathan Mar 22 '11 at 18:45
  • @Nathan: IIRC there's a FE_ALL flag, doubt it'd help much if you get exceptions for underflow already though. – Erik Mar 22 '11 at 18:46
  • Underflow cannot generate a NaN. – Stephen Canon Dec 28 '12 at 17:00
  • 1
    Underflows and overflows can, however, generate `inf`s and `0`s, which can quickly lead to `NaN`s. – Mike Jun 23 '14 at 18:59

2 Answers2

7

If any input has a quiet NaN value, it will cause the result of nearly any floating-point operation that consumes it to be NaN without raising the invalid exception.

The most likely explanation is that some data is being read from the wrong address, and that the read data (which may not even be floating-point data) happens to match a quiet NaN encoding. This can happen pretty easily, because the relatively common pattern 0xffff... encodes a quiet NaN.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
2

Are you doing any square root operation? If you try to compute a square root for a negative number as in sqrt(-1) then you will get a Nan. In this case you should get an 'Invalid Operation' exception though. Are you sure you are trapping correctly all exceptions? It seems like a numeric exception is untrapped somewhere in your code.

register
  • 399
  • 4
  • 14