Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Nan and Inf in Windows C++

Tags:

c++

math

I painfully learned today that Nan and Inf have serious side issues. Did you know for example that sqrtf(NaN) is more than 15 times slower and sqrtf(-1) is 30 times slower (!!) than sqrtf(10.123132) - which is on its own a quite slow, floating point calculation!? You calculate rubbish, need ridiculous amounts of time for it and don't even realize it.

Ok, under Linux you can catch Nan and Inf bugs by throwing an exception when they occur:

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

How could you achieve that under Windows?

EDIT: the Benchmarking code:

float a,b;
a = 1.0 / 0;   //inf
a = -10;         //also nice
long c=0;
long time = SDL_GetTicks();

for (long i=1;i<=1000000;i++) {
   b=sqrt(a); 
}

ostringstream Help; Help << SDL_GetTicks()-time;

//RESULT SHEET
//sqrt(1): 21ms
//sqrt(10): 21ms
//sqrt(10.123): 20ms
//sqrt(-10);   390ms
//sqrt(+-NaN): 174ms
//sqrt(inf):  174
like image 311
Kenobi Avatar asked Feb 20 '13 21:02

Kenobi


1 Answers

If you're using Visual Studio, you can turn on floating point exceptions using the /fp:except option. See http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx.

The equivalent in code is #pragma float_control( except, on ). See http://msdn.microsoft.com/en-us/library/45ec64h6(v=vs.110).aspx.

At runtime you can use something like _controlfp( _MCW_EM, _MCW_EM ). See http://msdn.microsoft.com/en-us/library/vstudio/e9b52ceh(v=vs.110).aspx.

like image 174
Nate Hekman Avatar answered Oct 20 '22 04:10

Nate Hekman