comp.lang.c FAQ list
·
Question 14.9

Q:
How do I
set variables to, or
test for
IEEE NaN
(``Not a Number'')
and other special values?

A:
Many systems
with high-quality IEEE floating-point implementations provide
facilities
(e.g.
predefined constants,
and functions
like
isnan(),
either
as nonstandard extensions
in <math.h>
or perhaps
in
<ieee.h>
or
<nan.h>)
to deal with these values cleanly,
and
work is being done
to formally standardize such facilities.
A crude but usually effective test for NaN
can be written based on the fact that IEEE NaN's
never compare equal to anything,
even themselves;
therefore
a number that doesn't compare equal to itself
must be a NaN:

#define isnan(x) ((x) != (x))

Beware, though, that
non-IEEE-aware compilers may
optimize the test away.
(Note also that
even if you do have a predefined constant like NAN,
you cannot use it in comparisons like
if(x == NAN),
again because
NaN's do not compare equal to themselves.)

C99 provides
isnan(),
fpclassify(),
and several other classification routines.

Another
possibility
is
to format
the value in question
using
sprintf:
on
many systems
it
generates
strings like "NaN" and "Inf"
which you could compare for
in a pinch.

To initialize variables with these values
(and if your system does not provide cleaner solutions),
you may be able to get away with some compile-time
``arithmetic'':

double nan = 0./0.;
double inf = 1./0.;

Don't be too
surprised,
though,
if these don't work
(or if they abort the compiler with a floating-point exception).

(The most reliable way of setting up these special values
would use a hex representation of their internal bit patterns,
but initializing a floating-point value with a bit pattern
would require using a union or some other type punning mechanism
and
would obviously be
machine-dependent.)