I am compiling the following code with the -ffast-math
option:
#include <limits>
#include <cmath>
#include <iostream>
int main() {
std::cout << std::isnan(std::numeric_limits<double>::quiet_NaN() ) << std::endl;
}
I am getting 0 as output. How can my code tell whether a floating point number is NaN when it is compiled with -ffast-math
?
Note: On linux, std::isnan works even with -ffast-math.
Since -ffast-math
instructs GCC not to handle NaN
s, it is expected that isnan()
has an undefined behaviour. Returning 0
is therefore valid.
You can use the following fast replacement for isnan()
:
#if defined __FAST_MATH__
# undef isnan
#endif
#if !defined isnan
# define isnan isnan
# include <stdint.h>
static inline int isnan(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) > 0xff000000u;
}
#endif
On linux, the gcc flag -ffast-math
breaks isnan()
, isinf()
and isfinite()
- there may be other related functions that are also broken that I have not tested.
The trick of wrapping the function/macro in parentheses also did not work (ie. (isnan)(x)
)
Removing -ffast-math
works ;-)
来源:https://stackoverflow.com/questions/7263404/mingw32-stdisnan-with-ffast-math