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 :

addition type float


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Par défaut addition type float
    Bonjour.

    J'utilise le compilateur visual c++ 2008, processeur pentium4.

    Voici une opération avec des doubles :

    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
     
    #include <iostream>
     
    using namespace std;
     
    void main(){
     
      double d1 = 5946100.5;
      double d2 = 5946048.0;
      int iVal = 4000;
     
      double dDelta = d1 - d2;
      dDelta /= (double)iVal;
     
      for(int i = 0; i < 4000; i++)
        d2 += dDelta;
     
      cout << d2;
    }
    A la sortie, d2 = 5946100.4999....;

    Voici la même chose avec des flottants :

    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
     
    #include <iostream>
     
    using namespace std;
     
    void main(){
     
      float f1 = 5946100.5f;
      float f2 = 5946048;
      int iVal = 4000;
     
      float fDelta = f1 - f2;
      fDelta /= (float)iVal;
     
      for(int i = 0; i < 4000; i++)
        f2 += fDelta;
     
      cout << f2;
    }
    A la sortie, f2 = 5946048;

    L'addition ne se fait pas.

    Pouvez-vous me dire ce que je n'ai pas compris avec les nombres flottants.

    PS : mode debug sans optimisation.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Salut

    La réponse est très simple, fDelta est trop petit. Je m'explique. En float, tu as 1 bit de signe, 11 bits pour l'exposant et 23 bits pour le nombre, ce qui te donne une précision d'environ 7 à 8 décimales après la virgule (en écriture scientifique, bien sûr).

    Maintenant regarde tes nombres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f2 =      5946048.0
    fDelta =        0.00000000220735
    fDelta est largement inférieur à la valeur minimale possible pour être ajoutée à d2. En clair : le processeur doit arrondir fDelta, et il est arrondi à 0,00. Donc 0 tout court, donc rien.

    En double, tu vas aller jusqu'à 16 décimales. Donc ton reliquat va bien être ajouté, mais je crois que tu perds quand même de la valeur avec les chiffres que tu montrent. Ton dDelta va être arrondi à plutôt 0,0000000022.

  3. #3
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    Ce que tout informaticien devrait savoir sur les nombres réels

    Amen.

    @jblecanard: tention que le nbr de décimal n'est pas une mesure pertinente. Les réels ont une représentations qui s'elargit au fur et a mesure que les nombres augmentent. Ca + les dénormaux.

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Dia,
    Citation Envoyé par Joel F Voir le message
    @jblecanard: tention que le nbr de décimal n'est pas une mesure pertinente. Les réels ont une représentations qui s'elargit au fur et a mesure que les nombres augmentent. Ca + les dénormaux.
    Oui, il a parlé de nombre de décimales, mais il a manifestement parfaitement compris qu'il s'agit du nombre de chiffres significatifs.

    Reste bien entendu le problème de vocabulaire.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    perso je recherche une doc un peu plus détaillée

  6. #6
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Par défaut
    Bonjour.

    Merci pour vos réponses. Enfin début de réponse...

    On ne doit pas avoir la même calculette. Disons que la calculette de windows me donne un fDelta de 0,013125. ((5946100.5 - 5946048.0) / 4000).


    Est-ce que cette valeur de fDelta est fausse (j'ai fait une erreur) ?
    Dans le cas où cette valeur est juste, cela remet-il en cause vos raisonnements ? (qui me semblent pertinents pour une valeur de fDelta de 0.00000000220735 mais pas pour 0,013125).

    Joel F, est-il possible de me résumer le lien que tu m'as donné (pour mon cas précis), qui puisse me permettre de comprendre. Ou bien dois-je lire ce pavé... ?

    PS : habituellement je gère les nombres réels à la main. Intuitivement j'avais compris qu'il ne fallait pas faire confiance au processeur... Là je travaille sur un programme où la précision n'est pas de rigueur. Et je me rends compte que c'est vraiment le bordel...
    J'ai tout réécris le programme avec des doubles, mais j'aimerai comprendre.

  7. #7
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    Citation Envoyé par moldavi Voir le message
    Joel F, est-il possible de me résumer le lien que tu m'as donné (pour mon cas précis), qui puisse me permettre de comprendre. Ou bien dois-je lire ce pavé... ?
    En gros, les nombres réels représenté discrétement ont des comportements contre-intuitifs. Je ne peux que te conseiller de le lire car il apporte énormément de précision sur pas mal de chose.

    Citation Envoyé par moldavi Voir le message
    PS : habituellement je gère les nombres réels à la main. Intuitivement j'avais compris qu'il ne fallait pas faire confiance au processeur...
    Non, le processeur fait son travail proprement, le pb vient souvent des développeurs qui veulent faire des choses qui n'ont pas de sens ou des compilos qui nous jouent des tours en basculant sans nous le dire entre represenation interne 80 bits et representation mémoire 32 bits par le jeu des copies registres/mémoires sur lesquelles ont a peu de controle.

  8. #8
    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
    Citation Envoyé par moldavi Voir le message
    Joel F, est-il possible de me résumer le lien que tu m'as donné (pour mon cas précis), qui puisse me permettre de comprendre. Ou bien dois-je lire ce pavé... ?
    Je plussoie, si on veut faire des calculs numériques sérieux, il vaut mieux lire le pavé...

    Mais si on ne veut pas, juste quelques astuces qui marchent parfois :
    - On stocke les gros volumes de données avec la précision qui a du sens pour elles, mais on fait les calculs dans la précision maximale disponible.
    - Préférer les calculs directs aux accumulations
    - Faire les calculs en diverse précisions, ou avec une bibliothèque de calcul par intervalles, permet de se faire une idée si on est dans un cas où les calculs sont problématiques.
    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.

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    La premiere chose, c'est de ne pas confondre reels et flottants. Tant qu'on s'imagine que les flottants sont une modelisation suffisemment fidele des reels pour qu'on puisse l'utiliser sans en maitriser les differences, il y aura des problemes.

    Citation Envoyé par guillaume07 Voir le message
    perso je recherche une doc un peu plus détaillée
    http://www.springer.com/birkhauser/m...-0-8176-4704-9

    Citation Envoyé par moldavi Voir le message
    Dans le cas où cette valeur est juste, cela remet-il en cause vos raisonnements ?
    Les float on a peu pres 6 chiffres significatifs. Tu est toujours au dessous de la difference observable.

    Joel F, est-il possible de me résumer le lien que tu m'as donné (pour mon cas précis), qui puisse me permettre de comprendre. Ou bien dois-je lire ce pavé... ?
    Le probleme des resumes, c'est que les gens en sortent des recettes (du genre "il ne faut jamais tester l'egalite deux flottants" ou "les flottants decimaux n'ont pas les problemes des flottants binaires") et le probleme est tel que les recettes simplifient trop le probleme; on tombe facilement dans des cas ou elles ne sont pas applicables si on n'a pas compris leur mode de fonctionnement (il y a des cas ou l'egalite est le test a faire, et de toute maniere l'introduction d'un epsilon rend l'egalite non transitive ce qui n'est pas particulierement intuitif non plus; en fait les flottants decimaux ont quasiment tous les problemes des flottants binaires et quelques uns en plus).

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Je voulais bien entendu parler du nombre de chiffres significatifs, merci de m'avoir remis dans le droit chemin du vocabulaire juste .

    Citation Envoyé par moldavi Voir le message
    On ne doit pas avoir la même calculette. Disons que la calculette de windows me donne un fDelta de 0,013125. ((5946100.5 - 5946048.0) / 4000).
    La calculette de windows travaille très certainement avec un modèle de données encore plus précis. Moi, j'ai fais le calcul avec C++, le résultat est donc tronqué.

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

Discussions similaires

  1. [type float ] problème d'affichage
    Par you98 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 14/11/2005, 08h06
  2. Précision du type float
    Par cj227854 dans le forum C
    Réponses: 5
    Dernier message: 02/11/2005, 20h54
  3. insérer une valeur de type float dans une abse de données
    Par Stephane_br dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/11/2005, 10h47
  4. Pb de formatage de champs de type float
    Par FrankyNormand dans le forum XMLRAD
    Réponses: 9
    Dernier message: 05/05/2005, 12h37
  5. [MS-SQL][ADO] précision du type FLOAT
    Par Le Lézard dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/09/2004, 15h30

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