C/C++ NaN constant (literal)?
Asked Answered
A

5

159

Is this possible to assign a NaN to a double or float in C/C++? Like in JavaScript you do: a = NaN. So later you can check if the variable is a number or no.

Acapulco answered 22/5, 2013 at 12:1 Comment(1)
Here I show how various NaNs look like when generated by different means: #18118908Derickderide
L
223

In C, NAN is declared in <math.h>.

In C++, std::numeric_limits<double>::quiet_NaN() is declared in <limits>.

But for checking whether a value is NaN, you can't compare it with another NaN value. Instead use isnan() from <math.h> in C, or std::isnan() from <cmath> in C++.

Leveloff answered 22/5, 2013 at 12:7 Comment(12)
Or you can compare the number to itself – x == x returns false iff x is NaN.Gaddi
@Archie: I don't think that's guaranteed in either language.Leveloff
@MikeSeymour Not by the language standard but as far as I know it should work if the compiler claims to be IEEE compliant.Heifetz
@Pixelchemist: Indeed, it's an option if you need obfuscation but not portability. Personally, I prefer portability without obfuscation, so I won't suggest it myself.Leveloff
minor note: NAN is a float, not a double. linkBrothers
@MikeSeymour (x == x) == false is guaranteed in Java, see grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…Formyl
Thanks for this, I just solved a problem with an external library that just refused to compile properly because it did not understand what NAN meant.Munshi
std::numeric_limits<double>::quiet_NaN() doesn't seem to be a constant in MSVC++2013.Richburg
Does std::isnan(a) return true if a is -nan?Grantee
What about if you can't use std::numeric_limits? Is there some other way to get NaN, such as a constant defined by dividing zero by zero, or is that a bad idea?Intrigue
> Or you can compare the number to itself – i have seen bugs from the compiler optimising this out. Always do an explicit check. Hunting this down is such a nightmare that its not worth the zero gain from doing it vs. any robust method.Refutation
Simon, there isn't a -NaN. It's just NaN. If you evaluate -NaN you get NaN. There are a bunch of wierd NaNs that no-one uses, and std::isnan() should return true for all of them. Or at least the quiet NaNs, I don't know if it will signal if passed a signalling NaN.Sperrylite
F
33

As others have pointed out you are looking for std::numeric_limits<double>::quiet_NaN() although I have to say I prefer the cppreference.com documents. Especially because this statement is a little vague:

Only meaningful if std::numeric_limits::has_quiet_NaN == true.

and it was simple to figure out what this means on this site, if you check their section on std::numeric_limits::has_quiet_NaN it says:

This constant is meaningful for all floating-point types and is guaranteed to be true if std::numeric_limits::is_iec559 == true.

which as explained here if true means your platform supports IEEE 754 standard. This previous thread explains this should be true for most situations.

Fainthearted answered 22/5, 2013 at 12:28 Comment(0)
D
9

This can be done using the numeric_limits in C++:

http://www.cplusplus.com/reference/limits/numeric_limits/

These are the methods you probably want to look at:

infinity()  T   Representation of positive infinity, if available.
quiet_NaN() T   Representation of quiet (non-signaling) "Not-a-Number", if available.
signaling_NaN() T   Representation of signaling "Not-a-Number", if available.
Diskson answered 22/5, 2013 at 12:5 Comment(1)
+1. Wikipedia has some information on quiet NaN and signaling NaN.Megalopolis
D
7

Is this possible to assign a NaN to a double or float in C ...?

Yes, since C99, (C++11) <math.h> offers the below functions:

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

which are like their strtod("NAN(n-char-sequence)",0) counterparts and NAN for assignments.

// Sample C code
uint64_t u64;
double x;
x = nan("0x12345");
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = -strtod("NAN(6789A)",0);
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = NAN;
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);

Sample output: (Implementation dependent)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)

... check if the variable is a number or no.

Use isnan(), std::isnan() from <math.h>, <cmath>.

Daffie answered 19/5, 2020 at 23:13 Comment(6)
What are the differences between outputs for different strings? Which one should we use in typical numerical code?Geryon
@Geryon x = NAN; fills most needs, else x = nan("0x12345"); is a clear way to specify a payload. Payload content differences is implementation defined. Commonly the MSBit of the 52-bit payload is a quiet / signaling flag.. See NAN.Daffie
Great examples, thank you very much. When should we use for example x = nan("0x12345"); instead of a general NAN? I mean why do we need to say 0x12345 is a nan?Reticle
@afp_2008 When not-a-number is implemented, there are usually many non-a-numbers. Often quiet and signaling NANs are implemented. When code wants to return something other than the default NAN, perhaps to signify quiet/signaling or some other meta data, nan("some_numeric_string"). This is a bit of a re-hash of this. If you need more, perhaps post a specific question? IIRC, one system tagged with the low bits of address to help facilitate where the NAN originated.Daffie
@chux-ReinstateMonica fyi, the provided link does not work.Reticle
@afp_2008 Curious, worked for me to get to my prior comment to quant_dev.Daffie
A
-18

yes, by the concept of pointer you can do it like this for an int variable:

int *a;
int b=0;
a=NULL; // or a=&b; for giving the value of b to a
if(a==NULL) 
  printf("NULL");
else
  printf(*a);

it is very simple and straitforward. it worked for me in Arduino IDE.

Amphibiotic answered 28/9, 2020 at 12:33 Comment(4)
NULL and NaN are actually not the sameAftermath
yes, they are basically different, but using NULL or NaN is same in the sense of checking if the variable is a number or no.Amphibiotic
"it worked for me" but is not related to the question at all. The question is how to assign NAN to a float or double. This answer does not contain NAN or any float or double.Mallis
>using NULL or NaN is same in the sense of checking if the variable is a number or no. Not quite - many comparisons with NaN operate differently from this.Hamman

© 2022 - 2024 — McMap. All rights reserved.