float f = (float)'a';
if(f < 0){
}
else if(f == 0){
}
else if(f > 0){
}
else{
printf("NaN\n");
}
f
won't be greater/equal/less than 0
if it's a NaN
.
But how to produce such a f
in the first place?
I tried various ways to produce a NaN
,but none work..
To produce a nan, there are a few ways:
1) generate it manually (read
ieee754
to set up the bits properly)2) use a macro. GCC exposes a macro
NAN
. It's defined in math.hThe general way to check for a nan is to check
if (f == f)
(which should fail for nan values)For nan, the exponent bits in the float representation should all be set to 1 (float consists of a signed bit, a set of exponent bits and a set of mantissa bits)
For hosted C implementations, one can do a
#include <math.h>
and use theNAN
macro if defined. For instance, with GCC, it is implemented by a builtin:(__builtin_nanf (""))
.For freestanding C implementations (on which the
<math.h>
header may not be available) or when theNAN
macro is not defined (which might happen even though NaN's may be supported), one can generate a NaN with a floating-point operation such as0.0 / 0.0
. However, there may be several issues with it.First, such an operation also generates an exception, with a possible trap on some C implementations. One can make sure that it is computed at compile time with:
Another issue is that Microsoft Visual C++ (at least some versions) attempts to evaluate
0.0 / 0.0
at compile time (even when this expression is in an arbitrary place in the code) and complains about its validity. So, the solution here is the opposite one: make sure that the compiler will not evaluate it at compile time, by doing:and then use
zero / zero
. Since these solutions are conflicting, one can test the compiler with preprocessor directives (#if
...) on specific macros.One may also choose a solution based on the NaN encoding, but there are also portability issues. First, the IEEE 754 standard does not completely define the encoding of a NaN, in particular the way to distinguish quiet and signaling NaNs (and hardware differs in practice); signaling NaNs will yield undefined behavior. Moreover, the IEEE 754 standard does not define how the bit string is represented in memory, i.e. the endianness may need to be detected. If these problems are solved, a union or an array of
unsigned char
with a pointer cast is fine to get the floating-point type. Do not use an integer with a pointer cast on its address to do type punning as this will break the C aliasing rules.nan is produced when we program contain value like 0.0/0.0 as said by @Dan Cecile OR sqrt(-1).
Following C program will produce a NaN. The second statement will result in a NaN.
Following will be the output of the program.
1.#QNAN0
From the GNU GCC manual
math.h
defines macros that allow you to explicitly set a variable to infinity or NaN. Since this is a part of C99 you can use the following macros with other c99 compliant compilers i hope.— Macro: float INFINITY An expression representing positive infinity. It is equal to the value produced by mathematical operations like 1.0 / 0.0. -INFINITY represents negative infinity.
You can test whether a floating-point value is infinite by comparing it to this macro. However, this is not recommended; you should use the isfinite macro instead. See Floating Point Classes.
This macro was introduced in the ISO C99 standard.
— Macro: float NAN An expression representing a value which is “not a number”. This macro is a GNU extension, available only on machines that support the “not a number” value—that is to say, on all machines that support IEEE floating point.
You can use ‘#ifdef NAN’ to test whether the machine supports NaN. (Of course, you must arrange for GNU extensions to be visible, such as by defining _GNU_SOURCE, and then you must include math.h.)
for further information you can see here: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html
You can either use
NAN
macro, or simply one ofnan/nanf
functions to assign a nan value to a variable.to check if you are dealing with a nan value, you can use
isnan()
. Here is an example:Running the code snippet above will give you this output:
Run the code yourself : http://ideone.com/WWZBl8
read more information : http://www.cplusplus.com/reference/cmath/NAN/