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 :

Conversion float en int


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 36
    Points : 19
    Points
    19
    Par défaut Conversion float en int
    Bonjour à tous et à toutes !

    J'ai développé un programme qui utilise que des entiers ou des flottants (pas de double), lors de la conversion d'un flottant vers un entier, j'ai un résultat inattendu et je souhaiterai si possible avoir une explication...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char** argv) {
        float t = 0.45;
        cout << "t = " << static_cast<int>(t*100) << endl;
        return 0;
    }
    Quand ce code est exécuté il me retourne "44", savez-vous pourquoi ?
    Merci d'avance,
    Nicolas.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    Bonjour,
    C'est parce que les floats ne sont pas exacts (en base 10). Ils sont précis (mais limités) en base 2.

    Du coup, 0.45 * 100 est probablement 44.999... ce qui donne le 44 que tu obtiens.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Bonsoir et merci pour cette réponse, j'utilise un double, ça fonctionne bien.

  4. #4
    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 nikobordx Voir le message
    Bonsoir et merci pour cette réponse, j'utilise un double, ça fonctionne bien.
    Il n'y a pas de raisons...
    Peut-être qu'en double, 0.45 est représenté par 0.4500000....0001, et que ça se passe bien, mais que 0.46 sera représenté par 0.4599999999... et que ça se passera mal.
    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.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    A vrai dire je n'ai que du 0.45, 0.35 et au pire 0.25, donc pas de souci en vue...

    Mais, y a t'il une solution pour que ce soit vraiment précis ?

  6. #6
    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
    J'ai développé un programme qui utilise que des entiers ou des flottants (pas de double)
    Deuxième règle d'emploi des flottants: on utilise le type le plus précis qu'on peut sauf si on sait ce que l'on fait.

    Citation Envoyé par nikobordx Voir le message
    A vrai dire je n'ai que du 0.45, 0.35 et au pire 0.25, donc pas de souci en vue...
    Je n'en suis pas aussi sûr que toi. (La valeur avec le moins de soucis, c'est 0.25 qui est représentable exactement dans les formats courants).

    Mais, y a t'il une solution pour que ce soit vraiment précis ?
    Défini précis. Il y a une infinité non dénombrable de réel, et en prime ceux-ci sont denses (entre deux réels, il y en a toujours une infinité non dénombrables d'autres). Être vraiment précis, il faut utiliser du calcul symbolique, avec son lot de problèmes et de limitations propres.

    Les flottants décimaux ne donnent guère qu'une illusion de précision (ils permettent de représenter une partie des réels dont l'expression décimale est simple), mais son en fait moins précis que les flottants binaires et ont tous les autres problèmes des flottants binaires, et quelques uns en plus. P.e. (a+b)/2 peut être strictement plus petit que min(a, b)).

    Bon, dans le cas présent, ton problème n'est pas un vrai problème de précision, c'est plutôt parce que tu tronques quand arrondir conviendrait mieux. Autrement dit, utilise lround() à la place de static_cast<int>
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    0.5 et 0.25 sont exactement représentés.
    Mais 3 * 0.25 ne l'est pas. en fait, même 0.1 ne l'est pas.

    En résumé, seules les sommes de puissances de 2 (1/2, 1/4, 1/8, ...) sont représentables exactement (et encore, pas toutes).
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    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 leternel Voir le message
    0.5 et 0.25 sont exactement représentés.
    Mais 3 * 0.25 ne l'est pas.
    3*0.25 est représentable exactement dans les formats courants et les processeurs incapables de faire cette multiplication exactement doivent tous être à la casse ou dans des musées pour ceux qui ont eu le plus de chance. (C'est 0.11 en binaire)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Si tu n'as que 3 valeurs, autant passer par un enum.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Merci à tous pour ces précisions !

    Finalement, j'ai remis un float et j'utilise "lroundf"

  11. #11
    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 nikobordx Voir le message
    Finalement, j'ai remis un float et j'utilise "lroundf"
    Pour quelle raison utiliser float plutôt que double?
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    A vrai dire il n'y a pas de raison particulière.
    Comme mon programme utilise des nombres à virgule (en très grand nombre), je suis parti sur des floats...

  13. #13
    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 nikobordx Voir le message
    A vrai dire il n'y a pas de raison particulière.
    Comme mon programme utilise des nombres à virgule (en très grand nombre), je suis parti sur des floats...
    1/ Moi j'ose pas utiliser les floats sans avoir estimé les erreurs et m'être assuré que c'était bon. 24 bits de précision relative, c'est vraiment trop imprécis pour prendre des risques.

    2/ Même quand on utilise des floats pour le stockage, on fait normalement les calculs avec des doubles autant que possible.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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

Discussions similaires

  1. Conversion float vers int
    Par jeremy75 dans le forum C++
    Réponses: 2
    Dernier message: 20/05/2014, 17h54
  2. Conversion float en int?
    Par romain1 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 06/09/2008, 19h44
  3. Conversion du type int à float
    Par @yoyo dans le forum Débuter
    Réponses: 9
    Dernier message: 16/01/2008, 13h22
  4. probleme de conversion float en int
    Par murreya dans le forum C++
    Réponses: 2
    Dernier message: 17/12/2005, 16h27
  5. Conversion float vers int
    Par vargasvan dans le forum C
    Réponses: 2
    Dernier message: 05/10/2005, 18h29

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