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 :

Résultat de division en entier au lieu de réel


Sujet :

C

  1. #1
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut Résultat de division en entier au lieu de réel
    Bonjour,

    Je fait une division qui me retourne un entier au lieu d'un réel, elle ne va pas jusqu'au bout.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int code=1234,modulo;
    float reste;
     
    modulo = (code%100);
    reste = (code/100);
    printf(">%d(%d)(%.2lf)<",code,modulo,reste); //Affiche 12.00
    Comment cela se fait-ce ?

    Merci d'avance.
    David.

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Parce que tu travaille avec des entiers :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int code=1234,modulo;
    float reste;
     
    modulo = (code%100);
    reste = ((float)code/100); // <= transforme ton entier en float et ça tourne
    printf(">%d(%d)(%.2lf)<",code,modulo,reste); //Affiche 12.00
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #3
    Expert éminent sénior
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    D'ailleurs prefere les double au float
    Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
    Mon espace perso[/B]

    La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]

  4. #4
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Bonjour Skyrunner et Trap D,

    Merci pour ces informations.

    Est-il possible de savoir pourquoi il est préferable d'utiliser des doubles ?
    David.

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    bonjour,
    Citation Envoyé par fr.comp.lang.c
    11.10 Faut-il préférer les double aux float ?


    La vitesse de traitement d'un double n'est pas forcément plus
    longue qu'un float, cela dépend du compilateur (de ses options)
    et du processeur. Ainsi avec l'exemple suivant, en remplaçant le
    typedef par float ou double, on s'aperçoit
    que sur un Pentium ou un PowerPC, le double est plus rapide
    à calculer que le float tout en ayant une précision plus grande.


    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 <math.h>
     
        typedef float reel;     /* float ou double */
     
        int main(void) {
            long i ;
            reel d = 3.0 ;
     
            for (i = 0; i < 100000000; i++) {
                d = cos(d) ;
            }
     
            (void)printf("%f\n", d);
            return 0;
        }

    Le C comprend des instructions mathématiques pour traiter les float
    directement au lieu de toujours passer par des double depuis la
    dernière norme (C99). Par exemple il existe cosf() en plus
    de cos(). En faisant des essais on s'aperçoit que dans
    notre exemple, le cosf() appliqué à un float devient
    aussi rapide que le cos() appliqué à un double.


    En conclusion, nous pouvons dire qu'il est préférable d'utiliser des
    double à la place des float, sauf lorsque la place
    mémoire devient critique.

  6. #6
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    En fait, je rencontre un autre problème...

    Ma chaine de numérique à convertir tient sur 10 caractères, alors, la conversion est éronnée car le type de donnée long (4 octets) ne peut pas contenir un numérique de cette longueur.

    Or avec le double ou float, ça ne marche pas, la valeur n'est pas la même !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    float code;
    char strTmp[11]="1072523722";
     
    sscanf(strTmp,"%f",&code); // Convertir le code en numérique
    printf("(%f)",code); // Affiche 1072523712.000
    Quelqu'un a t-il une solution ?
    David.

  7. #7
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Je ne suis pas un expert de la scanf() family donc je ne peux pas te dire que le probleme ne vient pas de la.

    Neanmoins ca me semble correct.

    Par contre, pourrais tu poster la maniere donc est initialisee strTmp ?
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  8. #8
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Bonjour Jack_serious,

    En fait, j'ai changé le code ci-dessus car il y a eu du changement.
    Voici mon code exact:
    (val est une chaine de 12 caractères initialisée à 107252372255)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int cle,res1,res2,res3;
    float code,reste;
    char strTmp[11]="";
     
    strncpy(strTmp,val,10); // Extraire les 10 premiers
    sscanf(strTmp,"%f",&code); // Stocker le code en numérique
    printf("0>(%f)<",code); // Affiche 1072523712.000 (au lieu de 1072523722.000)
    reste = code/100;
    printf("1>(%f)<",reste); // Affiche 10725237.000
    res1 = code-(100*reste);
    res2 = reste-(17*(code/1700));
    res3 = ((res1+res2)%100);
    printf("2>(%d)(%d)(%d)<",res1,res2,res3); // Affiche (0)(0)(0)
    while(!kbhit());
    David.

  9. #9
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par dacid
    Bonjour Jack_serious,

    (val est une chaine de 12 caractères initialisée à 107252372255)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    strncpy(strTmp,val,10); // Extraire les 10 premiers
    Citation Envoyé par man strncpy

    char *strncpy(char * restrict dst, const char * restrict src, size_t len);

    The strncpy() function copies not more than len characters into dst,
    appending `\0' characters if src is less than len characters long, and
    not terminating dst if src is len or more characters long.
    En francais: ta chaine val fait 12 caracteres. Donc strncpy() qui est une fonction caracterielle n'ajoute pas le sacro-saint '\0' a la fin de strTmp.

    En consequence, strTmp n'est pas une "chaine valide".

    Mais il semblerait qu'il y ait un probleme de formattage dans sscanf(). La par contre je ne sais pas.
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  10. #10
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Bin, le fait de l'initialiser (char strTmp[11]="" lui met des \0 partout, nan ?

    Donc, le fait de copier la chaine sans caractère de fin n'est pas un pb.

    J'ouvre un autre post car le problème a changé.
    David.

  11. #11
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par dacid
    Bin, le fait de l'initialiser (char strTmp[11]="" lui met des \0 partout, nan ?
    Non juste un.
    Si je pleure encore qu'un jour tu me reviennes,
    C'est que sans toi je suis comme un Roi sans sa Reine.

  12. #12
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Merci sorry j'avais un doute.

    Pour des chaines propres, le mieux c'est de se creer une "fonction maison" :

    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
     
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    char		*str_alloc(int size)
    {
      char		*str;
      int		i;
     
      str = malloc((size + 1) * sizeof(*str));
      if (!str)
        {
          perror(ERR_MSG);
          exit(1);                       //  exit() est un peu sauvage. Remplacer par return(0) si l'appli peut le gerer derriere.
        }
      for (i = 0; i <= size; i++)
        str[i] = 0;
      return (str);
    }
    Voila celle-la elle fait le cafe.

    Tu la fais une fois, et apres tu evites 99% des problemes de '\0'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char     *str;
    int        size;
     
    size = my_strlen(other_string_which_comes_from_another_place);
    str = str_alloc(size);
    /*
    ** Many usefull things
    */
    my_funky_function(str, everything_you_want);
    free (str);
    etc...

    Tu corriges comme ca les petits defauts de strcpy & co.
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par dacid
    Bin, le fait de l'initialiser (char strTmp[11]="" lui met des \0 partout, nan ?
    Oui. C'est garanti par la défintion du langage.
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par dacid
    Bin, le fait de l'initialiser (char strTmp[11]="" lui met des \0 partout, nan ?
    Oui. C'est garanti par la défintion du langage.
    Ah bon... C'est bon a savoir. Merci d'avoir dissipe cette erreur.
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Jack_serious
    Merci sorry j'avais un doute.

    Pour des chaines propres, le mieux c'est de se creer une "fonction maison" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      for (i = 0; i <= size; i++)
        str[i] = 0;
    Une façon compliquée d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memset (str, 0, sizeof *str * size + 1);
    Si on se limite au type char, on peut simplier le code avec calloc().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    char *str_alloc(int size)
    {
       char *str = calloc (size + 1, 1);
     
       if (!str)
       {
          perror (ERR_MSG);
          exit (EXIT_FAILURE);
       }
       return str;
    }
    Mais il n'est pas très sympathique pour l'utilisateur de sortir brutalement du code sur une simple erreur d'allocation mémoire...

    Dans la plupart des cas, un simple message suffit, et l'appli s'adapte...
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Une façon compliquée d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memset (str, 0, sizeof *str * size + 1);
    Decidement on en apprend tous les jours. Encore merci.

    Mais je trouve que la fonction maison a un apport didactique. Utiliser des fonctions dont on ne connait pas forcement les subtilites peut provoquer des bugs durs a deceler. (Quoique en l'occurence j'ai l'impression qu'on ne risque pas grand chose avec memset() au vu de sa description, arretes moi si je me trompe).

    Citation Envoyé par Emmanuel Delahaye
    Si on se limite au type char, on peut simplier le code avec calloc().
    Of course. J'ai mis malloc() par habitude. Plus generique.

    Citation Envoyé par Emmanuel Delahaye
    Mais il n'est pas très sympathique pour l'utilisateur de sortir brutalement du code sur une simple erreur d'allocation mémoire...
    Euh... Dans la plupart des cas quand on ne peut pas allouer de memoire, l'utilisateur ramasse un SegFault...

    Mais c'est juste. Je vais remplacer le exit() de mon post par une fonction moins sauvage.
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  17. #17
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Grrrr,
    Tout marchait bien jusqu'à ce que ça ne marche plus !

    Avec une autre donnée: 3321145038
    ne passe pas le test: res1 = (int)(code-(100*reste100));
    Ca devrait renvoyer 38, et ça renvoie -1.
    David.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/08/2014, 17h56
  2. Résultat exact division dont les membres sont des requêtes
    Par totoranky dans le forum Langage SQL
    Réponses: 2
    Dernier message: 07/08/2007, 14h51
  3. Diviser un entier de grande longueur par un autre entier
    Par DelphiManiac dans le forum Contribuez
    Réponses: 5
    Dernier message: 03/12/2006, 17h14
  4. Réponses: 4
    Dernier message: 06/09/2006, 11h45
  5. [SSE] Division nombres entiers
    Par jeremya dans le forum x86 32-bits / 64-bits
    Réponses: 15
    Dernier message: 10/05/2006, 17h49

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