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 :

operation sur les float


Sujet :

C++

  1. #1
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 130
    Par défaut operation sur les float
    Salut,
    j'ai une petite question concernant les float.
    soit f1 = 1500.0f
    soit f2 = -1500.0f
    si je fais f1 += f2, normalement j'ai zero mais en checkant mes variables au debugger, je constate que f1 = 0.00012456..

    Quelqu'un peut me dire pourquoi ?

    Parce que ca fout en l'air le reste de mes calculs.

    merci

  2. #2
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Ton problème est due au format de stockage des floats en mémoire, qui perd en précision.

    Pour comparer des floats en C++, il vaut mieux comparer avec un epsilon ( un chiffre très petit, représentant un seuil de tolérance à partir duquel une comparaison pourra être valide ou non ).

    Par exemple, au lieu de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       if ( f1 == f2 ) {
          [...]
       }
    Il vaut mieux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       if ( (f1 - f2) < epsilon ) {
          [...]
       }
    Et ainsi de suite. Comme ça tu es sûr de t'affranchir du problème de la précision.

    Peut-être existe-t-il des fonctions de comparaison des floats dans la bibliothèque standard ?

  3. #3
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 130
    Par défaut
    Bon je vois.

    A-t'on le meme probleme avec les double ?


    heu, je retire ma question (ca m'apprendra de parler avant de reflechir)

  4. #4
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 130
    Par défaut
    mon probleme reste donc entier.

    j'ai des classes vecteurs dont les membres sont de types float
    les operateur sont redefinis.
    Il faudrait donc que je les modifie tous ?

    ce n'est pas juste les comparaisons
    ce sont les soustractions ou additions qui me pose probleme.
    si je fais a = f1-f2 (avec f1=f2)) et que le resultat n'est pas a zero j'ai un petit souci pour calculer mon tan-1(a) par derriere.

  5. #5
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Ben je ne voudrais pas que tu modifies tout ton programme si il y a une option plus standard que celle que j'ai proposé.

    En fait, il faudrait que tu fasses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    a = f1 - f2;
    if ( a < epsilon ) {
       a = 0;
    }
    Mais ça implique pas mal de modif, à moins que ce soit dans une fonction..
    Attend de voir si il y a pas quelqu'un qui a une meilleure solution que moi

  6. #6
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 130
    Par défaut
    on va attendre un peu.
    je vais juste modifier les fonction qui me pose probleme.

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Il faut effectivement utiliser un espilon, mais attention le test correct est celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (std::abs(f1 - f2) < Epsilon)
    Pour epsilon, on peut utiliser std::numeric_limits<float>::epsilon() (inclure <limits>) qui représente le plus petit flottant tel que 1 + epsilon > 1. Ce n'est qu'une indication, car le choix de l'epsilon dépend en fait fortement de l'application et des grandeurs manipulées.

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Donc quelque chose de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (std::abs(f1 - f2) < f1 * Epsilon)
    peut-être ?

  9. #9
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Désolé de ne pas avoir pointé sur les bons renseignements, même si dans le principe j'avais bon.

    Il est vrai qu'il faut utiliser une valeur absolue..

    Par contre la remarque de Miles est pertinente, si le Epsilon de la librairie standard représente le plus petit flottant tel que 1+epsilon > 1, alors pour comparer si f1 est supérieur à f2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
       if( f1 > f2)
     
    devient
     
       if ( f1 * ( 1 + epsilon ) > f2 )
     
    ->
     
       if ( std::abs(f1*(1+epsilon) - f2) > 0 )
    Ou je délire ? Je suis mauvais en maths...

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    La c'est le cas où f2 est légèrement à f1 qui n'est pas pris en compte, non ? Ton code teste si f2 vaut f1 + un epsilon fixe défini à la compilation, pas si f1 et f2 sont les même nombre à un epsilon inférieur à une donnée définie à la compilation près.

  11. #11
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par grand's
    mon probleme reste donc entier.
    Ca tombe bien pour un problème de floats

    Désolé, je n'ai pas pu m'empêcher...Je

  12. #12
    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 : 50
    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
    La page suivante présente une introduction au problème :
    http://www.boost.org/libs/test/doc/components/test_tools/floating_point_comparison.html
    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.

  13. #13
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 116
    Par défaut
    J'ai déjà eu ce genre de problème et à ce moment (je travaillais sous TC++ 3), j'ai par hasard essayé de remplacer les flaot par des double.

    Et par magie ça a fonctionné...

    Pas sûr de savoir pourquoi mais bon... ça faisait ce que ça devait faire, c'est le principal

    Maintenant est-il intéressant de systématiquement remplacer les float par des doubles? Je crois que je connais la réponse ...

  14. #14
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    C'est un coup de bol, le problème existera aussi lorsque tu travailles sur des doubles et que tu veux comparer, tu prendras alors des long doubles ? Et quand tu travailleras en long double ?

  15. #15
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 116
    Par défaut
    Ben oui je m'en doute bien mais bon, il se fait que ça a marché à se moment là donc je le signale.
    Maintenant dans quelle gamme de valeur ce truc (mauvais en soit on est bien d'accord) fonctionne, je n'en sais rien.
    C'est possible voilà tout.

    Ceci dit je n'avais jamais pensé à cette histoire d'epsilon lorsque j'ai eu besoin d'appliquer ce "truc", même si on lisant ça je me suis dit "Ben oui, évidemment c'est logique". Comme quoi... heureusement qu'il y a les forums, hein?

Discussions similaires

  1. Operation sur les pointeurs
    Par Bahan dans le forum C
    Réponses: 8
    Dernier message: 24/05/2006, 17h24
  2. Operation sur les fichiers
    Par miron dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 06/05/2006, 15h45
  3. Opération sur les dates (Shell)
    Par argoet dans le forum Linux
    Réponses: 6
    Dernier message: 21/06/2005, 13h56
  4. [Math]probleme de precision de calcul sur les float
    Par calvin dans le forum Langage
    Réponses: 6
    Dernier message: 26/05/2005, 07h53
  5. operation sur les dates
    Par elendil dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 13/04/2005, 12h14

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