IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Calcul -> NAN en C++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut Calcul -> NAN en C++
    Bonjour à tous!

    Question de la mort qui tue: comment savoir que le résultat d'une opération est invalide?
    Je m'explique: si par exemple je fais une division par 0, comment je peux savoir que le contenu de ma variable n'est pas valide (équivalent NAN sur Excel par exemple)?

    Contexte: j'ai récupéré une DLL qui fait des calculs. Il y a des fonctions exportées qui renvoient des résultats (double) en fonction des paramètres d'entrée. Sauf que la personne qui a fait cette DLL n'a pa prévu les cas de calculs ambigües (division par 0, ...). Résultat, dès que je formate le résultat à problème dans une chaîne de caractères, je me récupère un magnifique "1.#INF".

    Y-a-t'il moyen de le savoir avant de formater le texte et faire une recherche sur le caractère '#' par exemple? Est-ce que je peux le savoir rien qu'avec la variable de retour?

    Merci d'avance.

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Une division par zéro produit un nombre tout à fait valide en C++, tu peux le tester avec std::numeric_limits< double >::infinity() par exemple.

    Pour tester NaN tu peux tester si un nombre est bien égal à lui-même (NaN est différent de lui-même).

    La représentation obtenue sous forme de chaîne de caractères avec les iostreams dépend de la plate-forme par contre...

    MAT.

  3. #3
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Une division par zéro produit un nombre tout à fait valide en C++
    Ca plante une division par zero, en tout cas avec gcc et le compilo de visual 2005.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    399
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 399
    Par défaut
    a l'execution, a partir d'une variable, ca ne plante pas. Par contre j'ai remarqué que ca faisait ramer le code a fond (enfin je ne c pas si c'etait la division en elle meme ou les calcul avec l'infini résultants)
    SPARK
    Moteur de particule C++ opensource avec modules de rendu OpenGL, Irrlicht et SFML

  5. #5
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par BainE Voir le message
    Ca plante une division par zero, en tout cas avec gcc et le compilo de visual 2005.
    Hmm pas chez moi...

    Avec VC2005 ce test passe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BOOST_AUTO_TEST_CASE( DivisionByZero )
    {
        static const float ZERO = 0.f;
        BOOST_CHECK_EQUAL( std::numeric_limits< float >::infinity(), 1.f / ZERO );
    }
    Avec g++ sous cygwin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    int main()
    {
      static const float ZERO = 0.f;
      if( std::numeric_limits< float >::infinity() == 1.f / ZERO )
        std::cout << "OK" << std::endl;
      return 0;
    }
    En faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ g++ -Wall divide_by_zero.cpp
    divide_by_zero.cpp: In function `int main()':
    divide_by_zero.cpp:6: warning: division by zero in `1.0e+0f / 0.'
     
    $ ./a.exe
    OK
    Qu'est ce que tu entends exactement par "ça plante" ?

    MAT.

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Une division par un flottant nul ne 'plante' pas (n'émet pas d'exception si c'est ce que tu voulais dire), mais raise un flag.
    Une division par un entier nul, par contre, envoie une exception CPU.

  7. #7
    Membre éclairé

    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Par défaut
    Citation Envoyé par Frifron Voir le message
    Par contre j'ai remarqué que ca faisait ramer le code a fond (enfin je ne c pas si c'etait la division en elle meme ou les calcul avec l'infini résultants)
    Oui le code devient très lent, mais pour aucune des deux raisons citées. Quand tu effectues un calcul avec un NaN (je ne suis pas certain si c'est au moment où tu l'obtiens ou au moment où tu l'utilise), le processeur émet une exception matériel, qui émet alors une interruption et fait donc passer le processeur en mode noyau (tout en branchant sur l'IRQ enregistrée, elle-même rendant généralement la main au noyau).
    Lorsque tu obtiens des NaN, imagine que ton processus se met à rendre la main au noyau a chaque calcul...

    Il y a quelques patchs pour le noyau Linux qui changent l'IRQ qui gère ce problème afin de diminuer la perte de vitesse lors de calculs très intensifs, mais ça ne fait pas des miracles... Sans compter qu'un NaN se propage... Vite.

    Citation Envoyé par nicroman Voir le message
    Une division par un flottant nul ne 'plante' pas (n'émet pas d'exception si c'est ce que tu voulais dire), mais raise un flag.
    Une division par un entier nul, par contre, envoie une exception CPU.
    Si c'est vraiment le cas, ce doit être paramétrable au lancement du noyau. Sur tous les systèmes que j'ai utilisés, ce n'est pas le cas, et des NaN avec des flottant y émettent bien des interruptions matérielles.

  8. #8
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    La représentation obtenue sous forme de chaîne de caractères avec les iostreams dépend de la plate-forme par contre...
    Du coup, est-ce le cas également pour la représentation d'infini?

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par spoutspout Voir le message
    Du coup, est-ce le cas également pour la représentation d'infini?
    Oui.

    Par exemple avec g++ sous cygwin on aura inf alors que msvc donnera 1.#INF.

    MAT.

  10. #10
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Je permets de remonter ce topic, car j'ai un autre problème du même genre. Le debuggeur de Visual me renvoie non plus 1.#INF, mais 1.#IND. Ceci apparait quand j'effectue un 0/0.
    J'ai recherché du côté des std::numeric_limits, mais je n'ai rien trouvé correspondant au IND (comme infinity() pour INF).
    J'ai deux questions:
    • Qu'est-ce que "IND"? Indéfini? Indivisible?
    • Comment faire le même genre de test que précédemment pour détecter le IND?
    Merci d'avance.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    399
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 399
    Par défaut
    J'imagine que c'est INDEFINITE. 0 / 0 a un résultat non défini. Ca doit être plus ou moins équivalent a un NaN.
    SPARK
    Moteur de particule C++ opensource avec modules de rendu OpenGL, Irrlicht et SFML

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Par défaut
    Indéfinit.

    A mon avis, c'est le moyen qu'a trouvé MSVC pour te dire qu'il a un NaN.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. résultat de calcul NaN
    Par insomai dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 12/08/2011, 18h20
  2. calcul: pourquoi NAN
    Par nsanabi dans le forum Langage
    Réponses: 11
    Dernier message: 25/10/2010, 13h14
  3. [Débutant] Calculer en excluant NaN et valeur 0
    Par kariboubou dans le forum MATLAB
    Réponses: 4
    Dernier message: 31/05/2010, 17h18
  4. Valeur de retour d'un petit calcul "NaN"
    Par lodan dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/01/2007, 21h10
  5. [NaN] Calcul d'une régression linéaire
    Par GLDavid dans le forum Langage
    Réponses: 1
    Dernier message: 24/10/2006, 12h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo