How do you write an NaN
floating-point literal in C?

- 3,291
- 4
- 35
- 48

- 205,094
- 128
- 528
- 886
-
@David: Oh really?! That's weird. I'm using GCC, but knowing an answer for Visual C++ would be helpful later too. – user541686 Apr 19 '11 at 09:17
-
Actually, I mis-spoke. The standard does talk about NaN, but it is optional. – David Heffernan Apr 19 '11 at 09:20
-
1possible duplicate of [How to use nan and inf in C?](http://stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in-c) – David Heffernan Apr 19 '11 at 09:22
-
1there's lots of good stuff at the duplicate Q – David Heffernan Apr 19 '11 at 09:23
-
@David: Ah okay... I did a search but everything was on C++; thanks! – user541686 Apr 19 '11 at 14:12
4 Answers
In C99's <math.h>
7.12 Mathematics <math.h>
[#5] The macro
NAN
is defined if and only if the implementation supports quiet
NaNs for the float type. It expands to a constant
expression of type float representing a quiet NaN. |

- 106,608
- 13
- 126
- 198
5.2.4.2.2/3:
floating types may be able to contain other kinds of floating-point numbers, such as ... infinities and NaNs. A NaN is an encoding signifying Not-a-Number. A quiet NaN propagates through almost every arithmetic operation without raising a floating-point exception; a signaling NaN generally raises a floating-point exception when occurring as an arithmetic operand.
7.12/5 (math.h):
The macro
NAN
is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN.
So you can get a value if your implementation supports NaNs at all, and if some or all of those NaNs are quiet. Failing that you're into implementation-defined territory.
There's also a slight worry with some of these floating-point macros that the compiler front-end might not know whether it supports the feature or not, because it produces code that can run on multiple versions of an architecture where support varies. I don't know whether that applies to this macro, but it's another situation where you're into implementation-defined territory - the preprocessor might conservatively claim that it doesn't support the feature when actually the implementation as a whole, as you're using it, does.

- 273,490
- 39
- 460
- 699
Using NAN
is better, but if you're on a system that has NaNs, 0.0/0.0
is an easy way to get one...

- 208,859
- 35
- 376
- 711
In C you can write a NaN floating point literal in the following way.
const unsigned long dNAN[2] = {0x00000000, 0x7ff80000};
const double LITERAL_NAN = *( double* )dNAN;
Please note that, this is not a standard way. On Microsoft C, it works fine.

- 1,354
- 15
- 26
-
1I like your style, but in general, it is recommended to use `union`s instead of `*(T*)` casts to do sneaky stuff like this. It might be more portable to do `union { uint64_t i; double d;} nan = { 0x7ff8000000000000};` and then use `nan.d` as NaN. Better to use the math.h header for portability. – Mark Lakata Jun 26 '15 at 05:49
-
Use of union does make sense. I think its a matter of style. The constant LITERAL_NAN can be used in code without the member access operator dot. When the definition style is concerned you suggestion is more meaningful. – MNS Jun 26 '15 at 10:00
-
@cmeeren I haven't tried it on x64 but it should work on x64 because IEEE 754 double precision is always 64 bits on both 32 bit and 64 bit OS. – MNS Sep 24 '15 at 12:58
-
3I'd like to point out to those who might not be aware, that this is not portable to systems where the correspondence of bytes from two longs to a double is not the same as presented in this answer, even though the system may have doubles according to the IEEE standard. (For instance on an architecture where longs are big endian, but doubles have the same byte order as on x86.) You mentioned Microsoft C in your answer, which pretty much defines the target architecture (Intel x86 or x86_64), but the significance regarding portability could easily be missed. – blubberdiblub Sep 24 '16 at 14:49
-
1This breaks strict aliasing rules and has UB in general. Namely, this is likely to not work on some versions of GCC. – Ruslan Nov 29 '16 at 14:30
-
@Ruslan I had indicated in the post that it is not a standard way of representing NaN. So it is quite possible that it might not work with other compilers. – MNS Nov 29 '16 at 16:51
-
@MarkLakata - AFAIK, the standard does no guarantee alignment of members in a union type. Thus, your two members may not be aligned (although this is unlikely in modern systems). For a specific compiler, checking with the documentation, this is definitely OK. See: https://stackoverflow.com/questions/3464448/ansi-c-unions-are-they-really-useful – ysap Aug 14 '20 at 19:38