Constante NaN C / C ++ (littérale)?

110

Est-ce possible d'attribuer un NaNà un doubleou floaten C / C ++? Comme en JavaScript vous: a = NaN. Ainsi, plus tard, vous pourrez vérifier si la variable est un nombre ou non.

exebook
la source
Ici, je montre à quoi ressemblent divers NaN lorsqu'ils sont générés par différents moyens: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

153

En C, NANest déclaré en<math.h> .

En C ++, std::numeric_limits<double>::quiet_NaN()est déclaré dans <limits>.

Mais pour vérifier si une valeur est NaN, vous ne pouvez pas la comparer avec une autre valeur NaN. Utilisez plutôt à isnan()partir <math.h>de C ou à std::isnan()partir <cmath>de C ++.

Mike Seymour
la source
20
Ou vous pouvez comparer le nombre à lui-même - x == xrenvoie falsessi xest NaN.
Archie
7
@Archie: Je ne pense pas que ce soit garanti dans les deux langues.
Mike Seymour
3
@MikeSeymour Pas par le standard du langage mais pour autant que je sache, cela devrait fonctionner si le compilateur prétend être conforme à IEEE.
Pixelchemist
37
@Pixelchemist: En effet, c'est une option si vous avez besoin d'obscurcissement mais pas de portabilité. Personnellement, je préfère la portabilité sans obfuscation, donc je ne le suggérerai pas moi-même.
Mike Seymour
9
note mineure: NAN est un flotteur, pas un double. lien
orion elenzil
23

Comme d'autres l'ont souligné, vous recherchez std::numeric_limits<double>::quiet_NaN()bien que je doive dire que je préfère le cppreference.com documents . Surtout parce que cette affirmation est un peu vague:

Uniquement significatif si std :: numeric_limits :: has_quiet_NaN == true.

et il était simple de comprendre ce que cela signifie sur ce site, si vous vérifiez leur section sur std::numeric_limits::has_quiet_NaNelle dit:

Cette constante est significative pour tous les types à virgule flottante et est garantie vraie si std :: numeric_limits :: is_iec559 == true.

qui , comme expliqué ici si des truemoyens de votre plate - forme prend en charge IEEE 754standard. Ce fil précédent explique que cela devrait être vrai dans la plupart des situations.

Shafik Yaghmour
la source
9

Cela peut être fait en utilisant les numeric_limits en C ++:

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

Voici les méthodes que vous voudrez probablement examiner:

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.
languitar
la source
6
+1. Wikipedia a des informations sur NaN silencieux et la signalisation NaN .
Drew Noakes
1

Est-ce possible d'affecter un NaN à un double ou float en C ...?

Oui, depuis C99, (C ++ 11) <math.h>offre les fonctions ci-dessous:

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

qui sont comme leurs strtod("NAN(n-char-sequence)",0)homologues et NANpour les affectations.

// 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);

Exemple de sortie: (en fonction de l'implémentation)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - Réintégrer Monica
la source
1
Quelles sont les différences entre les sorties pour différentes chaînes? Lequel devrions-nous utiliser dans un code numérique typique?
quant_dev le