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

  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 : 49
    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
    Points : 2 605
    Points
    2 605
    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
    Points : 3 156
    Points
    3 156
    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.
    Find me on github

  3. #3
    Membre chevronné
    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 : 43
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    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 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    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.
    Si les cons volaient, il ferait nuit à midi.

  5. #5
    Débutant
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Points : 176
    Points
    176
    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 : 49
    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
    Points : 2 605
    Points
    2 605
    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 chevronné
    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 : 43
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    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 éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    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).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    - 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.
    (Changer le mode d'arrondi est une autre technique; pour autant qu'on ait l'infrastructure pour).

    A noter que l'interpretation de ce genre de resultat est delicate -- le probleme pouvant provenir que l'algo est inadapte au calcul par intervalles (celui-ci est tres pessimiste si on ne prend pas les bonne precautions.)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  11. #11
    Membre chevronné
    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 : 43
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Je recommande a tout hasard de jouer avec la bibliothèque CADNA qui utilise un algo assez sioux pour detecter les pb d'arrondi, de cancellation et autre joyeusetés

  12. #12
    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
    Points : 3 156
    Points
    3 156
    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é.
    Find me on github

  13. #13
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Soa,

    Oui, la calculette Windows calcule avec environ 32 chiffres significatifs, soit environ 2 fois plus qu'avec le type double habituel.
    Si les cons volaient, il ferait nuit à midi.

  14. #14
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Meme en faisant le calcul en float on arrive a 13 millieme. jblecanard a du faire une typo quelque part.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  15. #15
    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 : 49
    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
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Merci pour ces réponses. A tout compris maintenant. En fait, plus il y a de nombres devant la virgule et moins il y a de nombres derrière la virgule... Je pensais que la mantisse figeait le nombre de chiffre significatif derrière la virgule.
    Mea Culpa... A pas bien suivi les cours.

    Comme je l'ai dit la précision n'a pas d'importance pour le programme sur lequel je travaille. Mais l'addition doit se faire quand même...


    PS : à Joel F. Je lirai ce pavé le jour où cela deviendra primordial. J'ai conservé le lien, je ne doute pas qu'un jour j'en aurai besoin. J'ai une dizaine de pavé à lire avant...

    A JolyLoic : la première remarque est très pertinente, je vais certainement l'appliquer.

    "Préférer les calculs directs aux accumulations", là je ne comprends pas le sens de cette phrase.

  16. #16
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    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.
    Citation Envoyé par moldavi Voir le message
    Merci pour ces réponses. A tout compris maintenant. En fait, plus il y a de nombres devant la virgule et moins il y a de nombres derrière la virgule...
    Gagné. Avec des float tu as 6 chiffres, avec des doubles 15.

    Comme je l'ai dit la précision n'a pas d'importance pour le programme sur lequel je travaille. Mais l'addition doit se faire quand même...
    Loic te donnait deux solutions. Je les ai mises en gras.

    PS : à Joel F. Je lirai ce pavé le jour où cela deviendra primordial. J'ai conservé le lien, je ne doute pas qu'un jour j'en aurai besoin. J'ai une dizaine de pavé à lire avant...
    Je continue à pense que la compréhension devrait en être indispensable avant d'être autorisé à utiliser les types flottants.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #17
    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 : 49
    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
    Points : 2 605
    Points
    2 605
    Par défaut
    Re.

    A Jean-Marc.Bourguet.

    C'est rigolo, j'étais justement en train de tenir compte des idées de JolyLoic, et j'ai modifié mon message alors que tu me donnais une réponse.

  18. #18
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par moldavi Voir le message
    "Préférer les calculs directs aux accumulations", là je ne comprends pas le sens de cette phrase.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      for(int i = 0; i < 4000; i++)
        d2 += dDelta;
    à remplacer par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (int i = 0; i < 4000; ++i)
       t = d2+i*dDelta;
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  19. #19
    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 : 49
    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
    Points : 2 605
    Points
    2 605
    Par défaut
    OK.

    Merci pour tout, et je vous rassure, j'approfondirai le sujet, pavé où pas...

+ 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