Question

J'ai des variables doubles (ou flottantes) qui pourraient être & "empty &" ;, comme ne contenant aucune valeur valide. Comment puis-je représenter cette condition avec les types intégrés float et double?

Une option serait un wrapper ayant un float et un booléen, mais cela ne peut & # 180; pas fonctionner, car mes bibliothèques ont des conteneurs qui stockent des doublons et non des objets qui se comportent comme des doublons. Une autre utilisera NaN (std :: numeric_limits). Mais je ne vois aucun moyen de vérifier si une variable est NaN.

Comment puis-je résoudre le problème de la nécessité d'un & "spécial &"; valeur flottante signifie autre chose que le nombre?

Était-ce utile?

La solution

Dans Visual C ++, il existe un _isnan(double) fonction que vous pouvez importer via float.h.

En C, il existe une fonction isnan(double) que vous pouvez importer via math.h.

En C ++, il existe une fonction (double) isnan que vous pouvez importer via cmath.

Comme d'autres l'ont déjà souligné, l'utilisation de NaN peut être très fastidieuse. Ils constituent un cas particulier qui doit être traité comme des pointeurs NULL. La différence est qu’un NaN ne provoque généralement pas de vidages de mémoire et d’échecs d’application, mais il est extrêmement difficile à repérer. Si vous décidez d'utiliser des NaN, utilisez-les le moins possible. La surutilisation de NaN est une pratique de codage offensive.

Autres conseils

Nous l'avons fait en utilisant NaN:

double d = std::numeric_limits<double>::signaling_NaN();
bool isNaN = (d != d);

Les valeurs NaN comparées pour égalité contre elle-même donneront la valeur false. C’est ainsi que vous testez NaN, mais qui ne semble valable que si std::numeric_limits<double>::is_iec559 est vrai (dans l’affirmative, il est conforme à ieee754 également).

En C99, il existe une macro appelée isnan dans math.h, qui vérifie également un nombre à virgule flottante pour une valeur NaN.

Ce n'est pas un type intégré, mais j'utilise généralement boost::optional pour ce genre de chose. Si vous ne pouvez absolument pas l'utiliser, un pointeur suffirait peut-être. Si le pointeur est NULL, vous savez alors que le résultat ne contient pas de valeur valide.

Une option serait un wrapper qui a un float et un booléen, mais cela ne peut & # 180; pas fonctionner, car mes bibliothèques ont des conteneurs qui stockent des doublons et non des objets qui se comportent comme des doublons .

C'est dommage. En C ++, il est simple de créer une classe basée sur un modèle qui se convertit automatiquement en attribut double réel (référence). (Ou une référence à un autre type d'ailleurs). Vous utilisez simplement l'opérateur de conversion dans une classe basée sur un modèle. Exemple: opérateur TYPE & Amp; () {valeur de retour; } Vous pouvez ensuite utiliser HasValue & Lt; double & Gt; partout où vous utiliseriez normalement un double.

Un autre utilisera NaN (std :: numeric_limits). Mais je ne vois aucun moyen de vérifier si une variable est NaN.

Comme litb et James Schek ont également remarqué, C99 nous fournit isnan ().

Mais faites attention à ça! Les valeurs nan rendent math & Amp; Logique vraiment intéressante! Vous penseriez qu'un nombre ne pourrait pas être à la fois NOT & Gt; = foo et NOT & Lt; = foo. Mais avec NaN, ça peut.

Il y a une raison pour laquelle je conserve une macro WARN-IF-NAN (X) dans ma boîte à outils. J'ai eu quelques problèmes intéressants survenus dans le passé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top