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 :

_finite vs _isnan vs 0x7FC00000


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Par défaut _finite vs _isnan vs 0x7FC00000
    voici mon 2eme bench.
    Il s'agit maintenant le méthode la plus rapide pour tester si un float est fini.
    le header <float.h> met à disposition 2 fonctions : _isnan et _finite.
    Une autre méthode consiste à comparer la valeur du float à 0x7FC00000, en convertissant son pointeur en un pointeur sur un long.
    voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    	int i;
    	int nvalid;
    	CString strt;
     
    MTDebugMessage(strModule, strFunction, "finite Début ");
    	nvalid=0;
    	for (i=0; i<m_nSize; i++)
    	{
    		if (_finite(m_pData[i]))
    			nvalid++;
    	}
    strt.Format("%d - %d",m_nSize , nvalid);
    MTDebugMessage(strModule, strFunction, "finite Fin -"+strt);
     
    MTDebugMessage(strModule, strFunction, "isnan Début ");
    	nvalid=0;
    	for (i=0; i<m_nSize; i++)
    	{
    		if (!_isnan(m_pData[i]))
    			nvalid++;
    	}
    strt.Format("%d - %d",m_nSize , nvalid);
    MTDebugMessage(strModule, strFunction, "isnan Fin -"+strt);
     
    MTDebugMessage(strModule, strFunction, "long lnan Début ");
    	nvalid=0;
    	unsigned long *pF;
    	for (i=0; i<m_nSize; i++)
    	{
    		pF=(unsigned long*) &(m_pData[i]);
    		if (*pF!=0x7FC00000)
    			nvalid++;
    	}
    strt.Format("%d - %d",m_nSize , nvalid);
    MTDebugMessage(strModule, strFunction, "long lnan Fin -"+strt);
    MTDebugMessage sert juste à ecrire un message daté dans un fichier de log.

    Résultat par colonne methode - nombre de valeurs - nombre de valid - temps:
    finite 12*582*912,00 4*388*733,00 0,078
    isnan 12*582*912,00 4*388*733,00 0,109
    0X7. 12*582*912,00 4*388*733,00 0,016

    Il n'y a pas photo, mieux vaut la méthode 3.

    Des remarques ?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    La méthode 3 est moins portable que les autres, puisqu'elle ne marche que sur les flottants IEEE754.
    Mais tant que tu restes sur des plate-formes comme les PC, cela ne devrait pas te poser de problème.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Rien dans la norme ne spécifie comment doivent être implémentés les float/double. Donc, ta méthode n'est pas portable.
    En plus, je me pose la question de l'utilité de ce genre de bench. L'optimisation vient rarement de petits arrangements de ce genre mais souvent sur l'algo et l'organisation du code.
    Vu l'évolution des compilateurs et du matériel, tu risque d'avoir un bench qui t'amène à prendre des décisions aujourd'hui qui seront contre-productives demain.
    J'avoue rester assez sceptique.

  4. #4
    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 tazer Voir le message
    voici mon 2eme bench.
    Il s'agit maintenant le méthode la plus rapide pour tester si un float est fini.
    le header <float.h> met à disposition 2 fonctions : _isnan et _finite.
    Une autre méthode consiste à comparer la valeur du float à 0x7FC00000, en convertissant son pointeur en un pointeur sur un long.

    Des remarques ?
    Ca calcule trois choses differentes, alors comparer les temps...

    _isnan(*) va retourner true que pour les NaN, false pour + et -inf et les nombres finis.
    _finite(*) va retourner true pour les nombres finis, false pour + et - inf et les NaN.
    0x7FC00000 va retourner true que pour un NaN particulier, false pour les autres Nan, + et - inf et les nombres finis.

    (*) si j'en crois les noms. Ce ne sont pas des fonctions definies par la norme. On va avoir isfinite, isnan, isinf, fpclassify, etc en C++0X, c'est deja en C99.

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