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 :

Problème de calcul et d'affichage de nombres réels


Sujet :

C

  1. #1
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut Problème de calcul et d'affichage de nombres réels
    Salut les programmeurs C,

    Je continue de découvrir le C mais je n'ai pas encore commencé l'apprentissage de la standard library en profondeur d'où cette question réellement a 2 centimes :

    À 2 cents plus exactement car j'ai fait un programme qui calcule ce dont vous avez besoin exactement pour payer une addition :
    On entre une somme en Euro et le programme calcule de combien de billets et pièces de chaque sorte vous avez besoin pour avoir l'appoint dont je vous épargne le code source.
    Le problème est que je demande l'entrée avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%f",&euro_entry) ;
    Le programme fait des modulo grâce à deux fonctions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int get_euro_mod(float s, int i) {
      return s/i ;
    }
     
    int get_cents_mod(float s, float i) {
     return s/i ;
    }
    successifs décroissant sur la somme entrée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    euro_500=get_euro_mod(euro_entry, 500) ;
    euro_entry=euro_entry- (get_euro_mod(euro_entry, 500)*500) ;
    // ... 
    cents_01=get_cents_mod(euro_entry, 0.01) ;
    euro_entry= euro_entry- (get_cents_mod(euro_entry, 0.01)*0.01) ;
    J'ai bien essayé de formater l'entrée afin d'avoir un float a deux chiffres, sans succès, après, le point pour que l'appoint soit bon: le résultat est faussé à cause de la longueur de la représentation de la somme entrée.
    J'ai clairement identifié le problème venant de scanf() qui ne permet pas de constante tel : "%.2f" ou du moins qui génère des warnings et des erreurs de traitement dans ce cas là.

    Merci pour vos réponses.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Salut,

    C'est bien de continuer le C

    Tu devrais regarder cette discussion : http://www.developpez.net/forums/d13...es-virgule-lu/

    Une solution peut-être de lire avec fgets(), de convertir en un nombre de centimes et de faire les calculs avec des entiers et un facteur de 100.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Salut
    Tu n'as pas bien explique ton soucis mais je pense que je le devine. Je crois que tu es confronte au probleme inherent a tous les ordis et tous les langages a propos du codage des decimaux.
    En effet, pour un ordi, un decimal est un nombre code a base de puissances negatives de 2. Donc 0.25 en base 10 etant 2^(-2) sera code 0.01 en base 2.

    Mais ce systeme ne marche pas pour tous les nombres et ainsi 0.6 sera code 0.1001001001001. Et dans l'autre sens si on decode ce chiffre, cela ne donne pas exactement 0.6 (cela donne 0.5999999 ou bien 0.6000001).

    D'ou la proposition de bktero de travailler exclusivement en centimes (entiers) quitte a convertir lors de la saisie et de l'affichage.

    Une autre solution serait d'utiliser une bibliotheque dediee a la gestion des decimaux. Ce genre de bibliotheque (qui existe en natif dans d'autres langages comme Python) code les decimaux chiffre par chiffre et effectue ensuite les calculs comme au primaire (chaque chiffre est pris independemment pour etre calcule avec chaque autre chiffre). Calculs (relativement) longs mais resultats garantis sans erreurs. Je sais qu'il en existe une ecrite en C qu'on peut telecharger et utiliser ensuite facilement dans ses codes C (on en parle parfois sur ce fofo)...
    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]

  4. #4
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos réponses,
    Je connaissait le problème des nombres a virgule flottante et les problèmes de la représentation binaire de ceux-ci , d'ailleurs j'ai écrit un module en python qui permet de manipuler: additionner, soustraire et multiplier des string binaires et la division ne fait pas partie des fonctions du module justement a cause de ce problème, c'est pas vraiment un module réellement utile mais ca fait un peu de lecture car il ,est documenter et les méthodes de calcules sont calquer sur les règles du calcule binaire vous pouvez éventuellement jeter un œil a mon module:
    Module python de manipulation et de calcule de nombres binaires.

    Seulement je pensait qu'il existait une possibilité plus trivial avec le format de la constante de scanf, mais comme vous infirmez, il va falloir formater l'entrée comme dit dans la FAQ.

    Merci pour vos réponses.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    vous pouvez éventuellement jeter un œil a mon module:
    Module python de manipulation et de calcule de nombres binaires.
    Juste pour le plaisir alors parce que Python possede deja le module "decimal" qui gere de facon complete et exacte les calculs sur nombres decimaux...
    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]

  6. #6
    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
    Hai,
    Citation Envoyé par Sve@r Voir le message
    Juste pour le plaisir alors parce que Python possede deja le module "decimal" qui gere de facon complete et exacte les calculs sur nombres decimaux...
    De manière générale, ou spécifique pour la monnaie ?

    Car si c'est "général", alors c'est impossible : on tombe très souvent sur des nombres qui ont une infinité de décimales, il faut donc bien les limiter quelque part.
    Si les cons volaient, il ferait nuit à midi.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par droggo Voir le message
    Hai,

    De manière générale, ou spécifique pour la monnaie ?

    Car si c'est "général", alors c'est impossible : on tombe très souvent sur des nombres qui ont une infinité de décimales, il faut donc bien les limiter quelque part.
    Le module "decimal", comme son nom l'indique, et aussi comme je l'ai mentionne dans mon post qui parlait de la gestion des nombres decimaux dans l'informatique, est la pour traiter les nombres... decimaux c'est a dire des nombres qui peuvent s'exprimer sous forme d'un nombre entier divise par une puissance de 10. Et non pour gerer les nombres rationnels ou irrationnels...

    Pour gerer les rationnels je ne sais pas ce que Python propose en natif mais j'ai de mon cote developpe ma propre librairie basee sur les calculs des fractions...
    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]

  8. #8
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Réponse rapide:
    Je n'arrive pas obtenir un float a précision de 2 chiffres après le virgule car écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <stdio.h>
    #include <stdlib.h>
    main() {
      float euro ;
      scanf("%f",&euro) ;
      printf("%f",euro) ;
    }
    donne :
    512.12
    512.119995
    Et en essayant obtenir la précision a deux chiffres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    #include <stdlib.h>
     
    main() {
      char *euro ;
      float res ;
      fgets(euro,255,stdin) ;
      res=strtof(euro,NULL) ;
      printf("%f",res) ;
    }
    J'obtiens le même résultat car je suppose que strtof fait la même opération de transformation sur la chaîne que avec scanf("%f",&euro) ???
    Je continuerai a chercher car le problème est plus grave que le formatage des entrées:
    j'ai remarquer que mes fonctions subissaient le même sort.
    Merci pour vos réponses.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Tu devrais regarder cette discussion : http://www.developpez.net/forums/d13...es-virgule-lu/

    Une solution peut être de lire avec fgets(), de convertir en un nombre de centimes et de faire les calculs avec des entiers et un facteur de 100.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *euro ;
      fgets(euro,255,stdin) ;
    L'erreur de segmentation te dira sûrement merci un jour de ne pas allouer 255 octets pour y faire pointer euro !

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Je continuerai a chercher car le problème est plus grave que le formatage des entrées
    Oui, c'est le probleme de la conversion des nombres decimaux (plus generalement des nombres flottants) en binaire puis reconversion en decimal. Perte de certaines decimales due a l'imprecision de la methode de conversion.

    Code c : 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>
    #include <stdlib.h>
    #define PRECISION              (255)
     
    int main() {
      char saisie[PRECISION + 1] ;
      unsigned long cents ;
      while(1)
      {
        fgets(saisie, PRECISION + 1, stdin);
        if (sscanf(saisie, "%lu", &cents) == 1) break;
        printf("saisie[%s] incorrecte - recommencez\n", saisie);
      }
      printf("%lu => %.02f",cents, cents / 100.0);
    }
    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]

  11. #11
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos réponses,
    pour Bktero :
    L'erreur de segmentation te dira sûrement merci un jour de ne pas allouer 255 octets pour y faire pointer euro !
    Excuser mais je vient du python et quand on parle de longueur on parle souvent de longueur de chaîne de caractères, par ailleurs je n'ai jamais utiliser malloc() et je suis en train de lire un livre qui l'utilise a outrance mais je n'en suis pas encore a la partie: allocation de la mémoire.
    Comme un char vaut 1 octet la chaine euro n'a pas besoin de 255 octets effectivement.
    mais concernant le float c'est une autre question.

    Sve@r merci d'avoir mis en lumière ce que l'on m'avait déjà dit au début du poste: de séparé la partie entière de la partie décimale pour le traitement, seulement je fait avec les moyens du bords pour l'instant mais est je suis tomber sur strtof qui ne change rien au problème comme dit plus haut.

    Je vais essayer d'arriver a un résultat exact, merci pour vos réponses éclairées.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Excuser mais je vient du python et quand on parle de longueur on parle souvent de longueur de chaîne de caractères, par ailleurs je n'ai jamais utiliser malloc() et je suis en train de lire un livre qui l'utilise a outrance mais je n'en suis pas encore a la partie: allocation de la mémoire.
    Moi je viens du C et suis passe il y a qq temps a Python ben je ne reviendrai pas au C. Devoir reinventer sans cesse la roue et ecrire 40 lignes de C pour faire un append() Python...
    En fait, quand tu utilises un pointeur (char *euro), la variable "euro" contient une valeur aleatoire car non initialisee. Mais quand tu demandes de remplir la zone avec n'importe quoi (une saisie, une autre variable, etc), ca va aller direct taper a l'adresse correspondant a cette valeur et commencer a y ecrire. Et la c'est la cata. Cette adresse est peut-etre celle d'une autre variable, etc. Et le pire c'est que si c'est l'adresse d'une autre variable non seulement le compilo ne te dira rien mais ton programme fonctionnera sans planter. Mais il te fera n'importe quoi (on appelle cela "comportement indetermine").
    Pour simplifier: chaque fois que tu utilises un pointeur (char *truc), tu n'as pas le droit d'aller ecrire dans la zone pointee (dans "*truc") si tu n'as pas d'abord ecrit "truc=une adresse valide" (bien souvent ce sera truc=malloc(...) ; la fonction malloc te renvoyant l'adresse d'une zone allouee donc forcement valide (sauf si allocation ratee mais c'est un autre soucis)
    De mon cote je ne me suis pas embete avec du malloc: j'ai declare un tableau de 255 octets et j'ai indique a fgets() de se limiter a ce nombre (mais definit au debut donc facilement modifiable => une seule modif, une recompilation et tout remarche)...

    Citation Envoyé par Luke spywoker Voir le message
    Sve@r merci d'avoir mis en lumière ce que l'on m'avait déjà dit au début du poste: de séparé la partie entière de la partie décimale pour le traitement, seulement je fait avec les moyens du bords pour l'instant mais est je suis tomber sur strtof qui ne change rien au problème comme dit plus haut.
    Petit detail: on ne t'a pas indique de separer les entiers des decimaux ; on t'a conseille de ne travailler qu'en centimes entiers. Apres tout, si la miche de pain coute 1.95E; elle coute alors 195 centimes...
    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]

  13. #13
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Brefs je suis parvenue a mes fins grâce a vos bon conseils,
    et je suis tellement content d'y être arriver que je vous montre ici le code source final un peu barban d'opérations consécutives répétitives mais c'est le prix a payer pour écrire en C.

    J'ai réussi en faisant entré l'utilisateur la somme en euro avec fgets() que dont je sépare le tableau résultant en deux partie:
    -la partie entière et la partie décimale.
    PS: il n'y a aucune vérification de l'entrée utilisateur et je n'ai pas pris la peine de commenter le 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAXSIZE 64 
    int get_euro_divmod(int f, int i) ;
    int get_cents_divmod(int f, int i) ;
    main(int argc, char argv[]) {
      int euro_500=0, euro_200=0, euro_100=0,euro_50=0,euro_20=0,euro_10=0, euro_5=0;
      int euro_2=0, euro_1=0 ;
      int cents_50=0, cents_20=0, cents_10=0, cents_5=0, cents_2=0, cents_1=0 ;
      int euro_entry, cents_entry ;
      char entry[MAXSIZE] ;
      char integer_part[]={} ;
      char decimal_part[]={} ;
      int c_entry, c_int_part, c_dec_part, bool ; // c_ == counter_
      printf("Enter the Euros value:\n") ;
      fgets(entry,MAXSIZE,stdin) ;
      c_int_part = c_dec_part = bool= 0 ;
      for (c_entry=0 ; c_entry < ((int) strlen(entry)) ; c_entry++) {
        if (entry[c_entry] == '.') {
          bool=1 ;
          continue ;
        }
        if (bool == 0 ) {
          integer_part[c_int_part]=entry[c_entry] ;
          c_int_part++ ;
        }
        else if (bool == 1 ) { 
          decimal_part[c_dec_part]=entry[c_entry] ;
          c_dec_part++ ;
        }
      }
      integer_part[++c_int_part]='\0' ;
      decimal_part[++c_dec_part]='\0' ;
      //printf("%s.%s",integer_part,decimal_part) ;    
      euro_entry=strtol(integer_part,NULL,10) ;
      cents_entry=strtol(decimal_part,NULL,10) ;
     
      euro_500=get_euro_divmod(euro_entry,500) ;
      euro_entry-=(get_euro_divmod(euro_entry,500) * 500 ) ;
     
      euro_200=get_euro_divmod(euro_entry,200) ;
      euro_entry-=(get_euro_divmod(euro_entry,200) * 200 ) ;
     
      euro_100=get_euro_divmod(euro_entry,100) ;
      euro_entry-=(get_euro_divmod(euro_entry,100) * 100 ) ;
     
      euro_50=get_euro_divmod(euro_entry,50) ;
      euro_entry-=(get_euro_divmod(euro_entry,50) * 50 ) ;
     
      euro_20=get_euro_divmod(euro_entry,20) ;
      euro_entry-=(get_euro_divmod(euro_entry,20) * 20 ) ;
     
      euro_10=get_euro_divmod(euro_entry,10) ;
      euro_entry-=(get_euro_divmod(euro_entry,10) * 10 ) ;
     
      euro_5=get_euro_divmod(euro_entry,5) ;
      euro_entry-=(get_euro_divmod(euro_entry,5) * 5 ) ;
     
      euro_2=get_euro_divmod(euro_entry,2) ;
      euro_entry-=(get_euro_divmod(euro_entry,2) * 2 ) ;
     
      euro_1=get_euro_divmod(euro_entry,1) ;
      euro_entry-=(get_euro_divmod(euro_entry,1) * 1 ) ;
     
      cents_50=get_cents_divmod(cents_entry,50) ;
      cents_entry-=(get_cents_divmod(cents_entry,50) * 50 ) ;
     
      cents_20=get_cents_divmod(cents_entry,20) ;
      cents_entry-=(get_cents_divmod(cents_entry,20) * 20 ) ;
     
      cents_10=get_cents_divmod(cents_entry,10) ;
      cents_entry-=(get_cents_divmod(cents_entry,10) * 10 ) ;
     
      cents_5=get_cents_divmod(cents_entry,5) ;
      cents_entry-=(get_cents_divmod(cents_entry,5) * 5 ) ;
     
      cents_2=get_cents_divmod(cents_entry,2) ;
      cents_entry-=(get_cents_divmod(cents_entry,2) * 2 ) ;
     
      cents_1=get_cents_divmod(cents_entry,1) ;
      cents_entry-=(get_cents_divmod(cents_entry,1) * 1 ) ;
     
      printf("You musst have:\n500.00: %i\n200.00: %i\n100.00: %i\n 50.00: %i\n 20.00: %i\n 10.00: %i\n  5.00: %i\n  2.00: %i\n  1.00: %i\n  0.50: %i\n  0.20: %i\n  0.10: %i\n  0.05: %i\n  0.02: %i\n  0.01: %i\n",euro_500, euro_200, euro_100, euro_50, euro_20, euro_10, euro_5, euro_2, euro_1, cents_50, cents_20, cents_10, cents_5, cents_2,cents_1) ; 
     
     
     
     
    }
     
    int get_euro_divmod(int f, int i) {
      return f/i ;
    }
     
    int get_cents_divmod(int f, int i) {
      return f/i ;
    }
    Si vous voulez faire des remarques donnez vous en a cœur joie je suis tout oui, mais le programme marche.
    Merci pour vos réponse et de part ce biais pour votre contribution.
    Le problème est résolus.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Si vous voulez faire des remarques donnez vous en a cœur joie je suis tout ouie, mais le programme marche.
    Beaucoup de repetitions de code. Et si un jour on rajoute un billet de 25E, faudra faire beaucoup de modifs pour integrer cette nouvelle monnnaie.

    La je ne suis pas chez moi mais des mardi, je te montrerai une autre facon de faire bien plus souple et bien plus optimisee basee sur un tableau de structures contenant d'un cote la monnaie a utiliser/diviser et de l'autre le libelle correspondant
    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]

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    La je ne suis pas chez moi mais des mardi, je te montrerai une autre facon de faire bien plus souple et bien plus optimisee basee sur un tableau de structures contenant d'un cote la monnaie a utiliser/diviser et de l'autre le libelle correspondant
    Chose promise...

    Code c : 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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    #include <stdio.h>
    #include <string.h>
     
     
    // Structure de découpage
    typedef struct {
    	char *libelle;
    	unsigned long valeur;
    	unsigned short nb;
    } t_monnaie;
     
    // Fonction de nettoyage monnaie
    void clean(t_monnaie *monnaie)
    {
    	t_monnaie *pt;
     
    	for (pt=monnaie; pt->libelle != NULL; pt++) pt->nb=0;
    }
     
    // Fonction de décomposition somme
    void calcul(t_monnaie *monnaie, unsigned long somme)
    {
    	t_monnaie *pt;
    	for (pt=monnaie; pt->libelle != NULL; pt++)
    	{
    		pt->nb=somme / pt->valeur;
    		somme%=pt->valeur;
    	}
    }
     
    // Fonction d'affichage somme
    void affiche(t_monnaie *monnaie, unsigned long somme)
    {
    	t_monnaie *pt;
    	printf("Pour composer la somme de %.02f, il sera nécessaire d'aligner:\n", somme / 100.0);
    	for (pt=monnaie; pt->libelle != NULL; pt++)
    	{
    		if (pt->nb == 0) continue;
    		printf("%u %s\n", pt->nb, pt->libelle);
    	}
    	fputc('\n', stdout);
    }
     
    // Fonction de conversion chaine contenant somme euro en centimes
    unsigned long convert(char *somme)
    {
    	char *pt;
    	unsigned short cents;
     
    	// Recherche "."
    	if ((pt=strchr(somme, '.')) != NULL)
    	{
    		// Blocage de la somme sur ce "."
    		*pt='\0';
     
    		// Récupération centimes situés après "."
    		cents=strtoul(pt+1, NULL, 10);
    	}
    	else
    		cents=0;
     
    	// Renvoi somme convertie en centimes
    	return strtoul(somme, NULL, 10) * 100 + cents;
    }	
     
    int main(int argc, char *argv[])
    {
        t_monnaie monnaie[]={
    		{"billets de 500 €", 50000, 0},
    		{"billets de 200 €", 20000, 0},
    		{"billets de 100 €", 10000, 0},
    		{"billets de 50 €", 5000, 0},
    		{"billets de 20 €", 2000, 0},
    		{"billets de 10 €", 1000, 0},
    		{"billets de 5 €", 500, 0},
    		{"pièces de 2 €", 200, 0},
    		{"pièces de 1 €", 100, 0},
    		{"pièces de 0.5 €", 50, 0},
    		{"pièces de 0.2 €", 20, 0},
    		{"pièces de 0.1 €", 10, 0},
    		{"pièces de 0.05 €", 5, 0},
    		{"pièces de 0.02 €", 2, 0},
    		{"pièces de 0.01 €", 1, 0},
    		{NULL, 0, 0},
    	};
     
    	char **arg;
    	unsigned long cents;
     
    	for (arg=argv + 1; *arg; arg++)
    	{
    		clean(monnaie);
    		cents=convert(*arg);
    		calcul(monnaie, cents);
    		affiche(monnaie, cents);
    	}
    }

    Résultat
    test.exe 1798.59 352.92
    Pour composer la somme de 1798.59, il sera nécessaire d'aligner:
    3 billets de 500 €
    1 billets de 200 €
    1 billets de 50 €
    2 billets de 20 €
    1 billets de 5 €
    1 pièces de 2 €
    1 pièces de 1 €
    1 pièces de 0.5 €
    1 pièces de 0.05 €
    2 pièces de 0.02 €

    Pour composer la somme de 352.92, il sera nécessaire d'aligner:
    1 billets de 200 €
    1 billets de 100 €
    1 billets de 50 €
    1 pièces de 2 €
    1 pièces de 0.5 €
    2 pièces de 0.2 €
    1 pièces de 0.02 €
    Le principe: un tableau contenant les éléments à manipuler. Bon là où c'est un poil critiquable, c'est que ce tableau contient à la fois les valeurs et à la fois le résultat pour composer la somme. En fait je voulais que l'utilisateur puisse utiliser le résultat pour autre chose qu'un bête affichage. Mais pour ça une solution bien meilleure aurait été de créer le résultat durant le calcul mais c'était plus compliqué (malloc etc).
    Mais à la base ce que je voulais te montrer, c'est que la force de ce genre de code réside dans
    • sa modularité (une fonction pour nettoyer le résultat, une autre pour calculer, une autre pour afficher). Il y en a même une qui se contente de convertir une chaine contenant une somme en € (style "123.45") en centimes (12345). Tu peux donc changer à vonlonté et non plus passer la somme dans la ligne de commande mais la faire saisir à l'utilisateur, cela marche aussi
    • la souplesse du tableau. Déjà inutile de se casser le tronc à connaitre sa taille pour les boucles. Une valeur supplémentaire à NULL et suffit de s'y caler. Ensuite rajoute-lui un billet de 25€ si tu en as envie, tu n'auras rien d'autre à écrire que la ligne adéquate parmi les autres lignes du tableau. Certains pourraient dire que faut penser quand-même à la mettre au bon endroit ce qui est vrai mais un petit qsort() au début peut même pallier à cet inconvénient


    Donc voilà. Essaye de t'inspirer de ces principes pour plus tard. Ecrire programme ce n'est pas seulement écrire un code qui fonctionne mais aussi essayer de penser à son évolutivité future...
    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]

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Une réalisation élégante, j'aime beaucoup.

    Par contre, j'aurai typé le "libelle" du t_monnaie en const char*, surtout qu'il est initialisé via une chaine littérale
    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

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par leternel Voir le message
    Une réalisation élégante, j'aime beaucoup.
    Merci

    Citation Envoyé par leternel Voir le message
    Par contre, j'aurai typé le "libelle" du t_monnaie en const char*, surtout qu'il est initialisé via une chaine littérale
    Arf suis pas trop à l'aise avec "quand mettre les const". Savais même pas qu'on pouvait en mettre dans une structure. On peut alors mettre aussi la valeur en const unsigned long non ???

    PS: j'avais oublié de mettre "cents" à 0 dans le cas où la somme n'a pas de ".". J'ai rectifié cet oubli...
    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]

  18. #18
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    la souplesse du tableau. Déjà inutile de se casser le tronc à connaitre sa taille pour les boucles. Une valeur supplémentaire à NULL et suffit de s'y caler. Ensuite rajoute-lui un billet de 25€ si tu en as envie, tu n'auras rien d'autre à écrire que la ligne adéquate parmi les autres lignes du tableau. Certains pourraient dire que faut penser quand-même à la mettre au bon endroit ce qui est vrai mais un petit qsort() au début peut même pallier à cet inconvénient
    Un de mes profs disait : "ajoutez de l'intelligence à vos données, il y aura moins de tests et cela sera plus lisible".
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  19. #19
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Un joli code

  20. #20
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Merci

    Arf suis pas trop à l'aise avec "quand mettre les const". Savais même pas qu'on pouvait en mettre dans une structure. On peut alors mettre aussi la valeur en const unsigned long non ???
    Ce n'est pas difficile, il suffit de choisir son dicton: "const toujours, mute plus tard" ou "dans le doute, const".

    en gros, pour un type T, ca donne:
    1. une variable? const si nécessaire
    2. un tableau, const si possible
    3. un pointeur? const T *! sauf pour un passage d'argument par référence variable, bien sûr (typiquement, un pointeur sur un contexte à modifier)
    4. T == char? alors const char *, sauf si la fin du monde est en train de se produire… et encore, dans ce cas là, envisage une solution de rechange
    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

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

Discussions similaires

  1. [Débutant] problème dans uimenu et d'affichage en temps réels
    Par Maria22 dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 19/08/2013, 13h48
  2. Formatage de l'affichage des nombres réels
    Par passkok dans le forum Langage
    Réponses: 8
    Dernier message: 26/11/2009, 19h29
  3. affichage des nombres réel
    Par tarek30 dans le forum JBuilder
    Réponses: 1
    Dernier message: 18/04/2009, 14h21
  4. [8.5]Problème pour calculer le nombre des personnes d'une liste
    Par Gotch59 dans le forum SAP Crystal Reports
    Réponses: 9
    Dernier message: 21/06/2007, 09h47
  5. Affichage des nombres réels!
    Par smail21 dans le forum Bases de données
    Réponses: 4
    Dernier message: 17/11/2005, 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