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 double > int


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut conversion double > int
    Bonjour,

    Je tombe sur un curieux problème de conversion de double à int.
    Voici mon code (C++ builder)...
    Avec le debugger jevois que C est égal à 3 qui est effectivement le résultat de 0.15 divisé par 0.05.
    MAIS, en convertissant C à res donc double vers int, res finit avec une valeur de... 2 !?!?

    Ce code donne quoi chez vous ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    		double A=0.15, B=0.05, C;
    		C=A/B;
    		int res=(int)C;
    		return 0;
    }

  2. #2
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut
    Je me réponds à moi-même :

    J'ai trouvé la solution suivante :
    C++11 added lround that helps to avoid precision loss on implicit double to long truncating cast:
    int intValue = (int) lround(dblValue)

    ... MAIS ça ne m'explique en rien le problème :
    Le double 3.00 ne fait pas l'objet d'un arrondi pour finir correctement en int avec une valeur de 3, n'est-ce pas ?

    Alors pourquoi le problème se pose-t-il ?

  3. #3
    Membre expérimenté
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Points : 1 376
    Points
    1 376
    Par défaut
    Bonjour et bonne année,

    il s'agit simplement d'un problème lié à la représentation des flottants. Teste avec le code suivant, tu comprendras mieux :

    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
     
    #include <stdio.h>
     
    int main(void)
    {
        double A=0.15;
        double B=0.05;
        double C=A/B;
     
        printf("A=%lf\nB=%lf\nC=%lf\n\n", A, B, C);
        printf("A=%.20lf\nB=%.20lf\nC=%.20lf\n\n", A, B, C);
        printf("(int) C = %d\n\n", (int) C);
     
        return 0;
    }
    Ta sortie devrait ressembler à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    A=0.150000
    B=0.050000
    C=3.000000
     
    A=0.14999999999999999445
    B=0.05000000000000000278
    C=2.99999999999999955591
     
    (int) C = 2
    Du coup avec le transtypage de double vers int, la valeur est tronquée : tu obtiens 2.

    Peut-être que la fonction lrint conviendrait mieux dans ton cas d'utilisation, non ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    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 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Le cast en int tronque.
    Si tu veux faire un arrondi mathématique, une méthode simple est d'ajouter 0.5 avant.
    int res = (int)(C + 0.5);
    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.

  5. #5
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut
    Merci à tous les deux pour vos solutions. J'applique et ça marche.

    Il subsiste tout de même dans mon esprit une incompréhension...
    Pour résumer, un double semble défini presque aléatoirement si l'on va jeter un coup d'oeil aux chiffres loin derrière la virgule ?
    C'est pour ça que l'on prend soin de définir un double =1.0 et pas simplement =1 ?
    Alors pour être 100% certain de ma definition de valeur je devrais écrire =1.0000000000000000 ?

  6. #6
    Membre expérimenté
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Points : 1 376
    Points
    1 376
    Par défaut
    Les flottants utilisent une représentation en base 2. Tout comme en base 10 où, par exemple, 1/3 n'a pas une représentation finie (⇒ 0,33333.....), 15/100 (=0,15) n'a pas une représentation finie en base 2 (0,00 1001 1001 1001 ....) d'où la valeur 0,14999999999999999445 affichée lorsque cette représentation est «convertie» en base 10 à nouveau. C'est le flottant le plus proche de 0,15(base 10) représentable en base 2.

  7. #7
    Membre régulier
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Points : 96
    Points
    96
    Par défaut
    Merci WhiteCrow. C'est clair !

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par devroot Voir le message
    C'est pour ça que l'on prend soin de définir un double =1.0 et pas simplement =1 ?
    Non, c'est juste une question de convention et de lisibilité. Ecrire double d=1.0 ou double d=1 ne change rien mais la première écriture sera plus rapidement assimilé par un autre lecteur du code "ah oui d est un double" (ok c'est écrit mais ça ne coûte rien de le redire).
    On peut aussi écrire "1.0" au lieu de "1" dans un calcul pour forcer le calcul à se faire en virgule flottante. Par exemple généralement on écrira x/2.0 plutôt que x/2 pour être sûr que la division de fasse en précision double et non int.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. [Conversion de type] Int -> Double
    Par Compufan dans le forum Débuter
    Réponses: 2
    Dernier message: 21/07/2013, 16h13
  2. conversion double en int
    Par medchafik dans le forum C++
    Réponses: 5
    Dernier message: 11/03/2012, 22h24
  3. conversion double/int sans perte d'informations
    Par leelooboss dans le forum Langage
    Réponses: 5
    Dernier message: 16/11/2010, 15h11
  4. Réponses: 8
    Dernier message: 30/09/2009, 09h21
  5. Conversion double -> int, problème étrange
    Par mickael9 dans le forum C++
    Réponses: 10
    Dernier message: 20/10/2008, 03h48

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