Considérons le code suivant:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
template<class T>
bool IsNaN(T t)
{
return t != t;
}
int main(int argc, char**argv)
{
double d1, d2;
sscanf(argv[1], "%f", &d1);
sscanf(argv[2], "%f", &d2);
double dRes = d1/d2;
cout << "dRes = " << dRes << "\n";
if(IsNaN(dRes))
cout << "Is NaN\n";
else
cout << "Not NaN\n";
}
Couple de questions:
dRes = inf
. Mais je m'attendais à dRes = NaN
ou quelque chose comme ça.Floating exception
. Quelle est la différence?inf
?Lorsque vous utilisez scanf()
, double
doit être lu avec %lf
, pas %f
. %f
convertira l'entrée en un float
de 32 bits, de sorte que les 32 premiers bits de vos variables seront remplis avec des données non valides et que les 32 derniers seront laissés comme des ordures.
Oui. #include <limits>
, puis std::numeric_limits<double>::quiet_NaN()
. Certains compilateurs (par exemple, gcc) fournissent également la macro NAN
NAME__ DANS <cmath>
.
Il n'y a pas de NaN ou d'infini pour les types entiers. La division par zéro pour l'entier provoquera une exception (SIGFPE) .
#include <cmath>
, puis std::isinf(x)
. Utilisez std::isfinite(x)
pour vous assurer que x
n'est pas NaN ou Infinity.
La fonction fpclassify
vous permettra d'inspecter une valeur en virgule flottante pour tous les cas particuliers.
Il se trouve dans <math.h>
sous forme de macro depuis C99 et dans <cmath>
sous forme de famille de fonctions pour float
, double
et long double
sous le nom surchargé std::fpclassify
depuis C++ 11.
cppreference a un bel exemple