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 :

Inverse d'un nombre décimal,


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut Inverse d'un nombre décimal,
    Bonsoir,

    Je me retrouve face à un problème "tout bête" que je ne sais pas résoudre...
    Comment prendre l'inverse d'un nombre décimal tel que 0.1, 0.001, 0.001... sous forme d'un int ?
    J'ai réussi à écrire en C le calcul approché de l'intégrale de 0 à 1 de 4/(1+x²) grâce à la formule de Simpson composée qui me donne une approximation de Pi.
    Je donne pour le moment la largeur du pas p (je veux laisser ce choix ultérieurement à l'utilisateur) : p =0.001 (par exemple) qui va me donner 1000 comme terme de la boucle de calcul.
    Le programme fonctionne avec déclaration de float p =0.001; et int nb=1000;
    mais si je m'avise d'écrire int nb; puis nb = floor(1/p) je déclenche une erreur à la compilation : warning : try to convert double to int...
    J'ai fini, difficilement, par comprendre pourquoi...
    Par contre, je ne sais pas comment contourner le problème : p=0.001, son inverse est 1000, nombre entier... Le problème vient du floor qui renvoie un double...
    Y a-t-il moyen de convertir un décimal (double ou float) dont on sait que sa partie décimale est nulle (c'est le cas de 1/p) en un nombre entier ?
    Je vous remercie par avance de votre indulgence.
    Et je remercie, dans la foulée, tout familier du C qui viendra me tirer du marais où je me suis enlisé.

    Cordialement,

    @+

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 620
    Points
    23 620
    Par défaut
    Bonjour,

    Tu peux tout-à-fait convertir un type numérique en un autre. Si le type-cible est moins précis que le type source, alors la valeur sera tronquée mais convertie quand même. Ici, convertir un flottant en entier est le meilleur moyen de se débarrasser de sa partie décimale.

    Il s'agit d'un warning, ce qui veut dire dans le cas présent que ton compilateur te prévient qu'il va faire implicitement et de lui-même une conversion. Si c'est bien ce que tu veux faire, tu peux transtyper (cast) ton nombre toi-même.

    Donc, dans le cas qui t'intéresse :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        int     x;
        float   y;
     
        y = 0.0001;
        x = (int)(1.0/y);

    Le tout est de s'assurer que l'on fait bien le calcul de l'inverse en float et que, seulement ensuite, on tronque le résultat uniquement, en le transtypant en entier. « 1.0 » plutôt que « 1 » sert à indiquer que le numérateur est flottant lui-aussi, sinon le compilo risque de convertir y en entier avant de faire le calcul.

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    si tu fais une intégration, tu n'es pas obligé de calculer le nombre de pas. Une simple boucle while peut suffire (c'est d'ailleurs plus propre que de calculer un nombre de pas de cette manière)

    Concernant le transtypage proposé plus haut, je te conseille plutôt la chose suivante : transtype en entier le résultat de la fonction floor. Je ne sais pas si la troncature est explicite, mais dans le doute, mieux vaut préciser si c'est un arrondi ou une troncature que tu fais.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Bonsoir,

    Décidément, quelle réactivité !!!
    Bon, le while m'oblige à gérer un compteur indépendant, alors qu'il est intégré dans le for...
    Je ne vois pas pourquoi le for est moins "propre" que le while ? J'essaierai ton truc (que je comprenne d'abord ce que ça veut dire et comment le faire), mais pas ce soir...
    En tous cas la solution de obsidian lève l'erreur.
    Pour mieux comprendre ce que j'ai raconté, voilà mon code :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    # include <stdio.h>
    # include <stdlib.h>
    # include <math.h>
     
    int main()
    {
        double s;
        double p = 0.001;
        double pi =M_PI;
        int a = 0,b = 1,k,nb;
        s=0;
        nb=(int)(1.0/p);
        printf("          Valeur Approchée de Pi\n\n");
        printf("Par approximation de l'intégrale de 0 à 1 de 4/(1+x^2)\n");
        printf("          Méthode de Simpson composée\n\n\n");
     
        for(k=1;k<nb;k++)
        {
         s+=(1+k%2)*4/(1+pow(a+k*p,2));
        }
        s=p/3*(4/(1+pow(a,2))+4/(1+pow(b,2))+2*s);
     
        printf("Valeur  connue de Pi = %.18f\n",pi);
        printf("Valeur obtenue de Pi = %.18f\n\n",s);
        system("pause");
        return 0;
    }
    Au passage, je constate que, question lettres accentuées, C est aussi "drôle" que Python...
    Bon, résultat exact à 0.1 près... bof ! bof !
    Parce que avant d'utiliser nb = (int)(1.0 / p); quand j'écrivais nb = 1000; j'obtenais un résultat exact à 10^-15 près...
    Hallucinant !!!
    Donc c'est le nb=(int)(1.0/p); qui ne donne pas le résultat escompté...
    Qui peut expliquer ça ?

    Merci d'avance

    @+

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Le tout est de s'assurer que l'on fait bien le calcul de l'inverse en float et que, seulement ensuite, on tronque le résultat uniquement, en le transtypant en entier. « 1.0 » plutôt que « 1 » sert à indiquer que le numérateur est flottant lui-aussi, sinon le compilo risque de convertir y en entier avant de faire le calcul.
    L'utilisation de 1.0 n'est pas indispensable ici, la division n'est entière que si les deux opérandes sont entières. Si au moins une des deux est réelle (ce qui est le cas puisque y est un float), la division est réelle (1 est converti en float, pas y en int).

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Bonjour,

    @gl ok ça éclaircit un certain nombre de choses.

    Bon, pour faire avancer mon problème, après nb = (int)(1/p);
    J'ai ajouté la ligne printf("%3d",nb);
    Et le résultat est 999 et non 1000... D'où ma valeur de Pi calculée à 3,13...
    Et tout le problème est là : la formule de Simpson utilisée demande un nombre d'intervalles pair, donc de tours de boucle pair...
    Là, il y a vraiment un problème de conversion, voire de représentation des nombres à virgule...

    Bon je pourrais tricher et modifier le For ainsi :
    For (k=0; k<nb+1;k++);
    ou
    nb = (int) (1/p)+1
    Mais ce n'est pas intellectuellement satisfaisant...
    Je viens aussi d'essayer
    double nb;
    nb=floor(1/p);
    printf("%4d",nb);
    Le résultat, là est 0...
    Affreux...

    Ma question est donc : comment faire pour que C me donne 1000 comme inverse de 0.001 ?
    Transformer 0.001 en 10^-3, récupérer l'exposant, changer son signe et écrire nb = 10^3 ?
    Ca ferait assez : je prends un bazooka pour détruire un moustique...

    Non, il doit bien y avoir un moyen direct rapide dans le langage C si réputé, au point que certains modules additionnels en Python sont écrits en... C.

    Quelqu'un connaît-il le moyen de faire sauter l'obstacle ? Dans ce cas, je le remercie par avance de prendre un peu de temps pour m'en faire part...

    @+

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    J'ai ajouté la ligne printf("%3d",nb);
    Et le résultat est 999 et non 1000...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double p = 0.001 ;
    int nb ;
    nb = (int) ( 1.0 / p ) ;
    printf ( "%3d" , nb ) ;
    m'affiche bien 1000

    Je viens aussi d'essayer
    double nb;
    nb=floor(1/p);
    printf("%4d",nb);
    Le résultat, là est 0...
    Affreux...
    1000 chez moi.
    (As-tu bien lié la librairie mathématique ?)

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    RE,

    Merci.
    J'ai recréé un programme de test en copiant/collant le morceau suggéré en exemple1 :
    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
    # include <stdio.h>
    # include <stdlib.h>
    # include <math.h>
     
    int main()
    {
        double p = 0.001 ;
        double np;
        int nb ;
        np=floor(1/p);
        nb = (int) ( 1.0 / p ) ;
        printf("np = %3d\n",np);
        printf ("nb = %3d\n\n" , nb ) ;
        system("pause");
        return 0;
    }
    Résultat


    Qu'est-ce qui ne va pas ?
    Ne serait pas suffisant d'écrire le # include <math.h> ?

    @+

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Après correction des warnings, j'ai toujours 1000 comme résultats :
    np = 1000
    nb = 1000

    Appuyez sur une touche pour continuer...
    Essaye avec un autre IDE, genre Code::Blocks ou autre. DevCpp n'est de toute façon plus maintenu, le problème vient peut-être de là (?).

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Re,

    ok, merci.
    J'ai téléchargé Code::blocks studio, je l'ai installé (il a l'air plus net que dev-c++), j'ai chargé mon script, je demande build and run et j'obtiens ça :

    Où sont les résultats, comment les visionner ?

    @+

  11. #11
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Salut.

    Citation Envoyé par jeroman Voir le message
    Essaye avec un autre IDE, genre Code::Blocks ou autre. DevCpp n'est de toute façon plus maintenu, le problème vient peut-être de là (?).
    L'IDE Dev C++ n'est certes plus maintenu, d'où la bonne initiative de passer à autre chose comme Code::Blocks , mais le compilateur est le même pour les deux EDI : GCC via le portage MinGW sous Windows. Les messages d'erreurs et warnings seront donc probablement les mêmes à flags égaux.

    Citation Envoyé par yoshik Voir le message
    J'ai téléchargé Code::blocks studio, je l'ai installé (il a l'air plus net que dev-c++), j'ai chargé mon script, je demande build and run [...] Où sont les résultats, comment les visionner ?
    Bah tu as programme qui s'exécute bien d'après ton screen : tu as un "hello world" d'affiché ... Cela signifie que tu as une fonction main () comme ci-dessous, dans ton fichier main.c (si tu as crée un nouveau projet) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main (void)
    {
         printf ("Hello world!");
         return 0;
    }
    Essayes de faire New => Empty file puis de coller ton fichier et de le compiler (en enregistrant d'abord sous le nom d'un fichier ayant l'extention ".c"). Petite parenthèse : le C n'est pas un langage de script ...

    Cordialement,
    Idriss

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Salut,

    Ok ! Merci. J'ai édité le main.c copié/collé le morceau de code...
    J'ai alors demandé Build and Run.

    Et bien même motif, même punition...

    J'ai toujours np=0 et nb = 999, donc le coupable n'était pas Dev-C++...

    Question donc : Jeroman et toi auriez vous un processeur Intel ? Moi j'ai un AMD Phenom X3...
    Cele pourrait-il venir de là ?

    @+

  13. #13
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Re

    J'ai testé et légèrement modifié ton code et voici le résultat avec gcc :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    idriss@precario-c700:~$ cat essai.c
    # include <stdio.h>
    #include <math.h>
     
    int main (void) /* Il est mieux de mettre void quand main ne prend pas de paramètres */
    {
        double s = 0, p = 0.001, pi =M_PI;
        int a = 0, b = 1, k, nb;
     
        nb=(int)(1.0/p);
        printf("          Valeur Approchée de Pi\n\n");
        printf("Par approximation de l'intégrale de 0 à 1 de 4/(1+x^2)\n");
        printf("          Méthode de Simpson composée\n\n\n");
     
        for(k=1;k<nb;k++)
        {
         s+=(1+k%2)*4/(1+pow(a+k*p,2));
        }
        s=p/3*(4/(1+pow(a,2))+4/(1+pow(b,2))+2*s);
     
        printf("Valeur  connue de Pi = %.18f\n",pi);
        printf("Valeur obtenue de Pi = %.18f\n\n",s);
     
        /* system("pause") n'est pas portable mais peut être remplacé par getchar () */
     
       return 0;
    }
    idriss@precario-c700:~$ gcc -lm -Wall -Wextra essai.c
    idriss@precario-c700:~$ ./a.out
              Valeur Approchée de Pi
     
    Par approximation de l'intégrale de 0 à 1 de 4/(1+x^2)
              Méthode de Simpson composée
     
     
    Valeur  connue de Pi = 3.141592653589793116
    Valeur obtenue de Pi = 3.138923318923125372
     
    idriss@precario-c700:~$
    Et pour celui-là :

    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
    idriss@precario-c700:~$ cat essai.c
    # include <stdio.h>
     
    int main (void) /* Il est mieux de mettre void quand main ne prend pas de paramètres */
    {
        double p = 0.001, np = 0; /* Il faut que np ait une valeur initiale */
        int nb = (int) (1.0 / p); /* nb = floor(1/p); ne sert à rien pour l'instant vu que la valeur de nb est aussitôt remplacée */
     
        printf("np = %3f\n", np); /* Attention à bien utiliser les bons formats */
        printf ("nb = %3d\n\n", nb);
     
        /* System ("pause") pas portable, peut être remplacé par : getchar() */
        return 0;
    }
    idriss@precario-c700:~$ gcc -Wall -Wextra essai.c
    idriss@precario-c700:~$ ./a.out
    np = 0.000000
    nb = 999
    Pour np, c'est normal : c'est sa valeur initiale qui reste inchangé ... Pour nb, ça devrait donner 1000 et non 999. Le résultat de nb est du à une mauvaise conversion double => int je pense. En laissant nb en double tu as bien 1000 ...

    Citation Envoyé par yoshik Voir le message
    Question donc : Jeroman et toi auriez vous un processeur Intel ? Moi j'ai un AMD Phenom X3...
    Cele pourrait-il venir de là ?
    J'ai Intel Celeron, architecture 32 bit sous Linux, mais ça ne doit pas venir de là AMHA.

    Cordialement,
    Idriss

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Ave,

    Suite à ton post, j'ai testé 2 choses en déclarant d'abord nb comme un double :
    1. J'ai écrit nb=1/p;
    et lancé le calcul
    2. Puis j'ai essayé nb=floor(1/p);
    et lancé le calcul...

    Dans les 2 cas la valeur calculée de pi est :
    3.1415926535897913
    la valeur donnée par M_Pi étant
    3.1415926535897931


    Conclusion,
    1. le floor est inutile,
    2. le passage de double à int est douteux : s'abstenir dans l'avenir ; alors que si je ne le fais pas en Python, le calcul se fait quand même agrémenté d'un bel avertissement me signalant que, dans les boucles for, on utilise des entiers pas des floats...

    Je peux considéré le problème résolu, même si chez certains aucun pb et chez moi aussi. N'empêche, j'aimerais bien comprendre...
    Autre piste : se pourrait-il alors que ce soit windows le coupable ? Tu as testé via linux...

    Merci encore

  15. #15
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    2. le passage de double à int est douteux....
    Non, le changement de type d'un réel en un entier se fait en prenant la partie entière. (Si elle est trop grande pour tenir dans cet entier, le résultat n'est pas portable).
    Ainsi :
    int i = 3.14 ; // i = 3
    int j = -3.14; // j = -3

    1. le floor est inutile
    C'est vrai si p est positif ou nul. Il y a une différence si p est négatif :

    int i = floor(3.14) ; // i =3
    int j = floor(-3.14); //j = -4

    ...d'un bel avertissement me signalant que, dans les boucles for, on utilise des entiers pas des floats...
    Bien que souvent utilisé pour incrémenter des valeurs, le for() ne fonctionne pas comme cela, mais en terme d'évaluation d'expressions. La nature des expressions utilisées n'est pas contrainte. La seule chose que la logique du for impose est que la première et la troisième expression aient des effets de bords (sinon elles ne servent à rien).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    C'est étonnant ces résultats. Moi aussi j'aimerais bien comprendre, ça m'intrigue.

    Pour répondre à la question, j'ai un AMD Athlon XP 2800+, et je tourne sous Win XP.

  17. #17
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    Quand je disais de faire un while, c'est plutôt quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    double integre_fonction( double borne_sup, double borne_inf, int nb_step)
    {
        double x, delta_x,sum ;
        sum = 0 ; 
        x = borne_inf ;
        delta_x = (borne_sup-borne_inf) / (nb_step-1) ;
        while(x<borne_sup) {
            sum = sum + delta_x * f(x)
            x = x + delta_x
        }
        return sum ;
    }
    Comme cela, tu ne gères pas d'index. (Je choisis la méthode des rectangles à titre d'example.)

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Re,

    j'avais pensé à une explication possible : le 1/0.001 me donne quelque chose comme 999.999... et le (int)(1/p); me renvoie alors 999 comme le floor.
    Bin, non...
    double p =0.001;
    double nb = 1/p;
    Et quand je demande à voir nb, il m'affiche 1000.0000...

    Par contre, je viens de mettre la main sur quelque chose :
    double p =0.001;
    int nx = (int) (1/p);
    nx vaut 999

    Mais
    double p =0.001;
    double nb = 1/p;
    int nx;
    nx = (int) nb;
    nx vaut 1000...

    Ce qui veut dire que si je stocke d'abord la valeur de 1/p dans un double, puis que je fais un (int) de ce double, j'ai la bonne valeur 1000, alors que faire directement nx =(int) (1/p) me renvoie 999...

    De plus en plus intrigant !!!

    @+

  19. #19
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Re

    Citation Envoyé par yoshik Voir le message
    J'avais pensé à une explication possible : le 1/0.001 me donne quelque chose comme 999.999
    C'est pas possible, mathématiquement : 1/0.001 donne exactement 1000 et non une valeur approchée 999.99999 ...

    Citation Envoyé par yoshik Voir le message
    alors que faire directement nx =(int) (1/p) me renvoie 999...
    Ici tu fait un cast (conversion explicite) de la valeur 1/p, cela devrait théoriquement prendre la partie entière de la valeur 1/p. D'ailleurs le cast est inutile, il me semble qu'il y a conversion implicite sans celui-ci.

    Cordialement,
    Idriss

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Re,

    Citation Envoyé par ok.Idriss
    C'est pas possible, mathématiquement...
    Je sais ça, heureusement : prof de maths retraité... ;-)

    D'autre part, il ne s'agit pas ici réellement de maths, mais de la représentation des nombres en mémoire d'une machine, ce qui n'est pas la même chose.
    J'ai vu un topic édifiant là-dessus et j'ai déjà rencontré des pbs de représentation en Python. Pas en C, diras-tu peut-être ? il faut que je retrouve ce topic qui tendait à montrer que ce genre de problèmes se rencontrait dans tous les langages (peut-être pas avec 0.001)...

    Enfin, juste au début de la ligne suivante j'écrivais : bin non !
    En info, je ne rejette plus d'idées a priori, je teste : c'est mon BrainStorming à moi...
    Ça m'a assez joué de tours au début : ma formation très carrée, hein...


    Mais revenons à ma "découverte"...
    Pourquoi :

    double p = 0.001;
    int nb;

    nb = (int) (1/p); me renvoie 999

    alors que

    double p = 0.001;
    double nx = 1/p;
    int nb ;

    nb = (int) nx; me renvoie 1000 ?

    @+

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/12/2005, 12h20
  2. [VB.NET] Nombre décimal
    Par Sadneth dans le forum ASP.NET
    Réponses: 8
    Dernier message: 25/11/2005, 12h41
  3. insérer un nombre décimale dans une table
    Par mouloudéen dans le forum Access
    Réponses: 4
    Dernier message: 02/10/2005, 21h29
  4. CRITERIA - Représentation binaire d'un nombre décimal signé.
    Par RamDevTeam dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 10/08/2005, 14h56
  5. [VB6]fonction inverse de Hex (nombres hexadécimaux)
    Par Guigui_ dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 08/10/2002, 19h31

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