web-dev-qa-db-fra.com

Comment vérifier inf (et | ou) NaN dans une double variable

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:

  1. Lorsque je passe 0 et 0 comme arguments, il génère dRes = inf. Mais je m'attendais à dRes = NaN ou quelque chose comme ça.
  2. NaN est-il représentable dans les variables doubles? D'ailleurs, toute variable?
  3. Quand j'ai changé le type de données de d1, d2, dRes en int et passé 0 et 0, j'ai eu un Floating exception. Quelle est la différence?
  4. Comment vérifier si la valeur d'une variable est égale à inf?
19
nakiya
  1. Lorsque vous utilisez scanf(), doubledoit être lu avec %lf, pas %f. %f convertira l'entrée en un floatde 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. 

  2. Oui. #include <limits>, puis std::numeric_limits<double>::quiet_NaN() . Certains compilateurs (par exemple, gcc) fournissent également la macro NANNAME__ DANS <cmath> .

  3. 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) .

  4. #include <cmath>, puis std::isinf(x) . Utilisez std::isfinite(x) pour vous assurer que xn'est pas NaN ou Infinity.

27
kennytm

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

0
Ben Voigt