Skip to content

Instantly share code, notes, and snippets.

@dankogai
Last active August 29, 2015 14:02
Show Gist options
  • Save dankogai/fbd25878666860851b2c to your computer and use it in GitHub Desktop.
Save dankogai/fbd25878666860851b2c to your computer and use it in GitHub Desktop.
Portable? isNan() and isFinite()
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdio.h>
#include <ctype.h>
int isNaN(double d) {
char buf[32];
sprintf(buf, "+%f", d);
return buf[1] == 'n';
}
int isFinite(double d) {
char buf[32];
sprintf(buf, "+%f", d);
return isnumber(buf[1]);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#if !defined(fpclassify) && __STDC_VERSION__ < 199901L
#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
#endif /* _UINT64_T */
#define DBL_EXP_MASK 0x7FF0000000000000ULL
#define DBL_MNT_MASK 0x000FFFFFFFFFFFFFULL
int isfinite(double f) {
return (*(uint64_t *)(&f) & DBL_EXP_MASK) != DBL_EXP_MASK;
}
int isnan(double f) {
return !isfinite(f) && (*(uint64_t *)(&f) & DBL_MNT_MASK) != 0;
}
#endif
#if !defined(fpclassify) && __STDC_VERSION__ < 199901L
#define isnan(x) ((x) != (x))
#define isfinite(x) ((x) == (x) && (x)+1 != (x))
#else

/usr/include/math.h of OS X Mavericks says:

These inline functions may fail to return expected results if unsafe
math optimizations like those enabled by -ffast-math are turned on.
Thus, (somewhat surprisingly) you only get the fast inline
implementations if such compiler options are NOT enabled.  This is
because the inline functions require the compiler to be adhering to
the standard in order to work properly; -ffast-math, among other
things, implies that NaNs don't happen, which allows the compiler to
optimize away checks like x != x, which might lead to things like
isnan(NaN) returning false.                                               
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment