7

After looking at another question on SO (Using NaN in C++) I became curious about std::numeric_limits<double>::signaling_NaN().

I could not get signaling_NaN to throw an exception. I thought perhaps by signaling it really meant a signal so I tried catching SIGFPE but nope...

Here is my code:

double my_nan = numeric_limits<double>::signaling_NaN();
my_nan++;
my_nan += 5;
my_nan = my_nan / 10;
my_nan = 15 / my_nan;
cout << my_nan << endl;

numeric_limits<double>::has_signaling_NaN evaluates to true, so it is implemented on my system.

Any ideas?

I am using ms visual studio .net 2003's C++ compiler. I want to test it on another when I get home.

Thanks!

Community
  • 1
  • 1
Jeffrey Martinez
  • 4,384
  • 2
  • 31
  • 36
  • I assume my_nan and num are supposed to be the same variable. If so please fix this. – Motti Nov 01 '08 at 21:09
  • MSVC has a known [bug](https://developercommunity.visualstudio.com/t/stdnumeric-limitssignaling-nan-returns-quiet-nan/155064) where `signaling_NaN()` actually returns a quiet NaN. – Jonathan Wakely Mar 04 '22 at 12:04

4 Answers4

6

You can use the _control87() function to enable floating-point exceptions. From the MSDN documentation on _control87():

Note:

The run-time libraries mask all floating-point exceptions by default.

When floating point exceptions are enabled, you can use signal() or SEH (Structured Exception Handling) to catch them.

bk1e
  • 23,871
  • 6
  • 54
  • 65
5

A word of warning: Using 3rd party DLLs may silently enable these exceptions. This is especially true for loading DLL's that are written in a language that enables them by default.

I've had that happen in two instances: Printing from an embedded browser control to a HP printer, and registering my DLL (that sets some initial values to NaN) from InnoSetup which is written in Delphi.

peterchen
  • 40,917
  • 20
  • 104
  • 186
  • 1
    I know opposite case when calling external DLL disables them. So from that point on all FPU exceptions are masked. So i have not any knowledge about potential errors in program. Such poorly written things are shame. All third party DLLs should return floating point exception masks to previous values. – truthseeker Aug 01 '12 at 10:01
1

From TFM:

cout << "The signaling NaN for type float is:  "
    << numeric_limits<float>::signaling_NaN( )
    << endl;

->

The signaling NaN for type float is: 1.#QNAN

where the 'Q' stands for 'Quiet'. Dunno why it would return that, but that's why it doesn't throw an exception for you.

Out of curiosity, does this work better?

const double &real_snan( void )
{
    static const long long snan = 0x7ff0000080000001LL;
    return *(double*)&snan;
}
Menkboy
  • 1,595
  • 10
  • 12
1

The key lies in numeric_limits<T>::has_signaling_NaN. Which value does this have for you? (The MSDN seems to suggest that it's always false for MSVC?)

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214