I've been using isinf
, isnan
functions on Linux platforms which worked perfectly.
But this didn't work on OS-X, so I decided to use std::isinf
std::isnan
which works on both Linux and OS-X.
But the Intel compiler doesn't recognize it, and I guess its a bug in the intel compiler according to http://software.intel.com/en-us/forums/showthread.php?t=64188
So now I just want to avoid the hassle and define my own isinf
, isnan
implementation.
Does anyone know how this could be done?
edit:
I ended up doing this in my source code for making isinf
/isnan
working
#include <iostream>
#include <cmath>
#ifdef __INTEL_COMPILER
#include <mathimf.h>
#endif
int isnan_local(double x) {
#ifdef __INTEL_COMPILER
return isnan(x);
#else
return std::isnan(x);
#endif
}
int isinf_local(double x) {
#ifdef __INTEL_COMPILER
return isinf(x);
#else
return std::isinf(x);
#endif
}
int myChk(double a){
std::cerr<<"val is: "<<a <<"\t";
if(isnan_local(a))
std::cerr<<"program says isnan";
if(isinf_local(a))
std::cerr<<"program says isinf";
std::cerr<<"\n";
return 0;
}
int main(){
double a = 0;
myChk(a);
myChk(log(a));
myChk(-log(a));
myChk(0/log(a));
myChk(log(a)/log(a));
return 0;
}
You could also use boost for this task:
#include <boost/math/special_functions/fpclassify.hpp> // isnan
if( boost::math::isnan( ... ) .... )
I've not tried this, but I would think
int isnan(double x) { return x != x; }
int isinf(double x) { return !isnan(x) && isnan(x - x); }
would work. It feels like there should be a better way for isinf, but that should work.
According to this, infinity is easy to check:
NaN is a bit more complicated because it doesn't have a unique representation:
Below is the code for double-precision floating-point case. Single-precision can be similarly written (recall that the exponent is 11-bits for doubles and 8-bits for singles):
int isinf(double x)
{
union { uint64 u; double f; } ieee754;
ieee754.f = x;
return ( (unsigned)(ieee754.u >> 32) & 0x7fffffff ) == 0x7ff00000 &&
( (unsigned)ieee754.u == 0 );
}
int isnan(double x)
{
union { uint64 u; double f; } ieee754;
ieee754.f = x;
return ( (unsigned)(ieee754.u >> 32) & 0x7fffffff ) +
( (unsigned)ieee754.u != 0 ) > 0x7ff00000;
}
The implementation is pretty straightforward (I took those from the OpenCV header files). It uses a union over an equal-sized unsigned 64-bit integer which you might need to correctly declare:
#if defined _MSC_VER
typedef unsigned __int64 uint64;
#else
typedef uint64_t uint64;
#endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With