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++

  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
    Merci � tous pour vos r�ponses.
    Apr�s divers essais, je peux vous dire:
    Citation Envoy� par Mat007
    Pour tester NaN tu peux tester si un nombre est bien �gal � lui-m�me (NaN est diff�rent de lui-m�me).
    Je n'ai pas pu v�rifier, mon retour �tant un double (et le == n'est pas valable sur un double ). Peut �tre sur un int?
    Citation Envoy� par Mat007
    Citation Envoy� par BainE
    Ca plante une division par zero, en tout cas avec gcc et le compilo de visual 2005.
    Hmm pas chez moi...
    Oui et non (j'utilise VS). Une division explicite dans le code t'attireras les foudres du compilateur:
    error C2124: division ou modulo par z�ro
    Une division par 0 "cach�e" n'emp�chera pas la compilation, te produiras �ventuellement un warning (pas syst�matique), mais plantera � l'ex�cution ("XXXX a rencontr� un probl�me et doit fermer....", je suis sous XP):
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    int iNum = 1;
    int iDen = 0;
    int iQuo = iNum/iDen;
    warning C4723: division potentielle par 0
    Sauf que dans mon cas, c'est-�-dire la division dans une DLL annexe et le r�sultat renvoy� dans le programme principal, le plantage n'intervient pas, et c'est cet esp�ce de NaN qui m'est renvoy�.
    Citation Envoy� par Mat007
    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.
    Effectivement, j'ai v�rifi� et je vais faire comme cela .
    Merci � tous!

  9. #9
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Citation Envoy� par spoutspout Voir le message
    Apr�s divers essais, je peux vous dire:Je n'ai pas pu v�rifier, mon retour �tant un double (et le == n'est pas valable sur un double ).
    Bien sur que si il est valable. NAN est garanti �tre le seul double non �gal � lui m�me. Il n'est pas garanti que

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 == 1
    Mais il est garanti que
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 == 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  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
    Mais ce n'est pas applicable � un retour de fonction car je ne peux pas deviner ce qui me sera renvoy�, et donc par rapport � quoi il me faut tester ce retour (mon but est juste de d�tecter si la valeur est valide, pas si elle est �gale � quelque chose).
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    double dMyVar = MyFonction(...);
     
    if(dMyVar == dMyVar)
        cout << "Valide";
    else
        cout << "Pas valide";
    Si ma fonction me renvoie "1.#INF0000..." (sous Visual, une fois format� en texte) c'est � dire NaN, c'est le "Valide" qui est affich�, ce qui est faux. Donc v�rifier un double en testant s'il est �gal � lui-m�me ne fonctionne pas.
    Ou alors je n'ai pas compris ce que vous m'avez sugg�r� .

    D'une mani�re g�n�rale, je ne fais jamais du "==" avec les double car �a pose quand m�me souvent probl�me. Par exemple, dans le test suivant, c'est "pas �gal" qui est affich�:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    double dVal1 = 0.1 + 0.1 + 0.1 + 0.1 + 0.1; // = 0.5
    double dVal2 = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1; // = 0.5 aussi
     
    if(dVal1 == dVal2)
        cout << "égal";
    else
        cout << "pas égal";

  11. #11
    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
    Infinity (INF) et Not-A-Number (NAN) ne sont pas la m�me chose.
    L'infini est un nombre, et c'est ce que tu obtiens dans ton cas lors d'une division par z�ro, et tu le testes avec == std::numeric_limits< double >::infinity() (ou avec !=).

    MAT.

  12. #12
    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
    OK, j'avais s�rement mal cibl� et/ou expliqu� mon probl�me.
    Merci

  13. #13
    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?

  14. #14
    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.

  15. #15
    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.

  16. #16
    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

  17. #17
    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 Frifron Voir le message
    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.
    Donc d�tectable avec un quiet_NaN() ?

  18. #18
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Citation Envoy� par spoutspout Voir le message
    Donc d�tectable avec un quiet_NaN() ?
    Comment?

    La seule maniere, c'est de voir s'il est egal a lui-meme. Si ce n'est pas le cas, tu as un NaN. En passant, il y a pas mal de NaN differents, en theorie ont pourrait initialiser toutes les variables float/doubles avec un et voir a la fin si on a du calcul qui fait intervenir des variables non initialisees et trouver une d'entre elles -- les operations prenant un ou plusieurs NaN en entree doivent retourner un de ceux-ci comme resultat.

  19. #19
    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 Jean-Marc.Bourguet Voir le message
    Comment?
    Ben de la m�me mani�re que pour le 1.#INF:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    double dProut = 51/0; // forcément ça compilera pas, mais c'est pour illustrer
     
    if(dProut == std::numeric_limits<double>::infinity())
        std::cout << dProut << std::endl;
    Faudrait que j'arrive � reprosuire ce 1.#IND pour tester quiet_NaN()... Je vais creuser �a

  20. #20
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Citation Envoy� par spoutspout Voir le message
    Ben de la m�me mani�re que pour le 1.#INF:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    double dProut = 51/0; // forcément ça compilera pas, mais c'est pour illustrer
     
    if(dProut == std::numeric_limits<double>::infinity())
        std::cout << dProut << std::endl;
    Faudrait que j'arrive � reprosuire ce 1.#IND pour tester quiet_NaN()... Je vais creuser �a
    Pour la troisieme fois dans ce fil, les NaN ne sont pas egaux a eux-memes.

+ R�pondre � la discussion
Cette discussion est r�solue.
Page 1 sur 2 12 Derni�reDerni�re

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