96 votes

Comment utiliser nan et inf en C?

J'ai une méthode numérique qui pourrait renvoyer nan ou inf en cas d'erreur, et pour des raisons de test, j'aimerais la forcer temporairement à renvoyer nan ou inf pour s'assurer que la situation est gérée correctement. Existe-t-il un moyen fiable, indépendant du compilateur , de créer les valeurs nan et inf en C?

Après avoir cherché Google pendant environ 10 minutes, je n’ai pu que trouver des solutions dépendantes du client.

94voto

Alok Singhal Points 33073

Vous pouvez tester si votre application a:

#include <math.h>
#ifdef NAN
/* NAN is supported */
#endif
#ifdef INFINITY
/* INFINITY is supported */
#endif

L'existence d' INFINITY est garanti par C99 (ou le dernier projet au moins), et "se développe à une expression constante de type float représentant positif ou non signé l'infini, si disponibles; d'autre à une constante positive de type float qui déborde à la durée de traduction."

NAN peut ou ne peut pas être défini, et "est définie si et seulement si l'application prend en charge calme NaNs pour le type float. Il se développe à une expression constante de type float représentant un calme NaN."

Notez que si vous comparez les valeurs à virgule flottante, et à faire:

a = NAN;

même alors,

a == NAN;

est faux. Une façon de vérifier pour NaN serait:

#include <math.h>
if (isnan(a)) { ... }

Vous pouvez également le faire: a != a pour tester si a est NaN.

Il est également isfinite(), isinf(), isnormal(), et signbit() macros en math.h en C99.

C99 a également nan fonctions de:

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

(Référence: n1256).

25voto

Thorsten S. Points 1756

Cela fonctionne à la fois en float et en double:

double NAN = 0.0 / 0.0

double POS_INF = 1.0 /0.0

double NEG_INF = -1,0 / 0,0;

Edit: Comme on l’a déjà dit, l’ancienne norme IEEE stipulait que de telles valeurs devraient créer des pièges. Mais les nouveaux compilateurs désactivent presque toujours les traps et renvoient les valeurs données car le trapping interfère avec la gestion des erreurs.

20voto

Aaron Points 5463

Un moyen indépendant du compilateur, mais non indépendant du processeur, d'obtenir ces éléments:

 int inf = 0x7F800000;
return *(float*)&inf;

int nan = 0x7F800001;
return *(float*)&nan;
 

Cela devrait fonctionner sur tout processeur utilisant le format à virgule flottante IEEE 754 (comme x86).

UPDATE: Testé et mis à jour.

17voto

J.Kraftcheck Points 91
double a_nan = strtod("NaN", NULL);
double a_inf = strtod("Inf", NULL);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X