Is there an isnan() function?
PS.: I'm in MinGW (if that makes a difference).
I had this solved by using isnan() from <math.h>
, which doesn't exist in <cmath>
, which I was #include
ing at first.
Is there an isnan() function?
PS.: I'm in MinGW (if that makes a difference).
I had this solved by using isnan() from <math.h>
, which doesn't exist in <cmath>
, which I was #include
ing at first.
After reading the other answers I wanted something that would pass through the floating-point comparison warning and would not break under fast math. The following code appears to work:
It seems to me that the best truly cross-platform approach would be to use a union and to test the bit pattern of the double to check for NaNs.
I have not thoroughly tested this solution, and there may be a more efficient way of working with the bit patterns, but I think that it should work.
This detects infinity and also NaN in Visual Studio by checking it is within double limits:
nan prevention
My answer to this question is don't use retroactive checks for
nan
. Use preventive checks for divisions of the form0.0/0.0
instead.nan
results from the operation0.f/0.f
, or0.0/0.0
.nan
is a terrible nemesis to the stability of your code that must be detected and prevented very carefully1. The properties ofnan
that are different from normal numbers:nan
is toxic, (5*nan
=nan
)nan
is not equal to anything, not even itself (nan
!=nan
)nan
not greater than anything (nan
!> 0)nan
is not less than anything (nan
!< 0)The last 2 properties listed are counter-logical and will result in odd behavior of code that relies on comparisons with a
nan
number (the 3rd last property is odd too but you're probably not ever going to seex != x ?
in your code (unless you are checking for nan (unreliably))).In my own code, I noticed that
nan
values tend to produce difficult to find bugs. (Note how this is not the case forinf
or-inf
. (-inf
< 0) returnsTRUE
, ( 0 <inf
) returns TRUE, and even (-inf
<inf
) returns TRUE. So, in my experience, the behavior of the code is often still as desired).what to do under nan
What you want to happen under
0.0/0.0
must be handled as a special case, but what you do must depend on the numbers you expect to come out of the code.In the example above, the result of (
0.f/FLT_MIN
) will be0
, basically. You may want0.0/0.0
to generateHUGE
instead. So,So in the above, if x were
0.f
,inf
would result (which has pretty good/nondestructive behavior as mentioned above actually).Remember, integer division by 0 causes a runtime exception. So you must always check for integer division by 0. Just because
0.0/0.0
quietly evaluates tonan
doesn't mean you can be lazy and not check for0.0/0.0
before it happens.1 Checks for
nan
viax != x
are sometimes unreliable (x != x
being stripped out by some optimizing compilers that break IEEE compliance, specifically when the-ffast-math
switch is enabled).This works:
output: isnan
There are three "official" ways: posix
isnan
macro, c++0xisnan
function template, or visual c++_isnan
function.Unfortunately it's rather impractical to detect which of those to use.
And unfortunately, there's no reliable way to detect whether you have IEEE 754 representation with NaNs. The standard library offers an official such way (
numeric_limits<double>::is_iec559
). But in practice compilers such as g++ screw that up.In theory one could use simply
x != x
, but compilers such as g++ and visual c++ screw that up.So in the end, test for the specific NaN bitpatterns, assuming (and hopefully enforcing, at some point!) a particular representation such as IEEE 754.
EDIT: as an example of "compilers such as g++ … screw that up", consider
Compiling with g++ (TDM-2 mingw32) 4.4.1: