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 :

Erreur de variable ou de pointeur ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut Erreur de variable ou de pointeur ?
    Bonjour,

    Mon code devrait me permette d'obtenir une somme prédéfinie en additionnant des nombres que l'on entre en mémoire dans un tableau, après en avoir demandé la taille.
    Par exemple, si j'ai 3 nombres, (prenons 20, 2 et 14) et que je souhaite obtenir la somme 34, alors le programme me renvoie 20 et 14.
    Un problème d'origine inconnue survient pourtant lorsque je saisis comme nombre "10.10, 20.10 et 3.8". Il est alors incapable de me dire que je peux obtenir le bon total en additionnant les 3 nombres.

    J'ai déjà essayé de remplacer mes float par des double, mais ça a empiré les choses. Si je place des int, alors tous les nombres que j'entre dans mon tableau se transforment en 0.00

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(int argc, char *argv[])
    {
        float Somme = 0.00 ;
        float Total = 0.00 ;
    /***************************************************************/
    /**                                                                               **/
    /**      La variable "Mt" signifie Montant.                     **/
    /**      Pour augmenter la lisibilité, on peut remplacer  **/
    /**      tous les "Mt" par le terme "Montant"                 **/
    /**                                                                               **/
    /***************************************************************/    
        int n=0;
     
        int NombreDeFactures = 0;
        int i=0;
        float* Mt = NULL; // Ce pointeur servira de tableau après l'appel du malloc
     
        // On demande le nombre de factures
        printf("Combien de factures dans ce mois ? ");
        scanf("%d", &NombreDeFactures);
     
        printf("Quelle est le total a obtenir?\n");
        scanf("%g", &Total);
     
        if (NombreDeFactures > 0) // Il faut qu'il ait au moins une facture 
        {
            Mt = malloc(NombreDeFactures * sizeof(float)); // On alloue de la mémoire pour le tableau
            if (Mt == NULL) // On vérifie si l'allocation a marché ou pas
            {
                exit(0); // On arrête tout
            }
     
            // On demande le Mt des factures une à une 
            for (i = 0 ; i < NombreDeFactures ; i++)
            {
                printf("Entrer le montant de la facture %d : ", i);
                scanf("%g", &Mt[i]);
            }
     
            // On affiche les factures stockées, une à une
            printf("*****************************************************************************\n");
            printf("*  A but verificatif, les montants des factures du mois sont les suivants : *\n\n");
            for (i = 0 ; i < NombreDeFactures ; i++)
            {
                printf("%10.2f CHF\n", Mt[i]);
            }
     
            switch (NombreDeFactures)
            {
               case 1:
                    Somme=Mt[0];
                    if (Somme!=Total)
                    {
                    printf("Mt = %f \n", Somme);
                    printf("Ce n'est donc pas la bonne facture \n");
                    }
                    else
                    {
                    printf("Mt ( %f ) équivalent au total ( %f ) \n", Somme, Total);
                    printf("C'est donc la bonne facture \n");
                    }
                    break;
               case 2:
                    if (Total==Mt[0])
                    {
                    printf("Somme = %f \n", Mt[0]);
                    printf("C'est la bonne facture \n");
                    printf("Il s'agit du Mt 0 \n");
                    }
                    else if (Total==Mt[1])
                    {
                    printf("Somme = %f \n", Mt[1]);
                    printf("C'est la bonne facture \n");
                    printf("Il s'agit du Mt 1 \n");
                    }
                    else if (Total==Mt[0]+Mt[1])
                    {
                    printf("Somme = %f \n", Mt[0]+Mt[1]);
                    printf("C'est la bonne facture. Il est possible d'obtenir le total voulu avec 2 Mts \n");
                    printf("Ce sont les montants 0 et 1 \n");
                    }
                    else
                    {
                    printf("Il n'est pas possible de parvenir au total voulu avec ces 2 Mts\n");
     
                    }
                    break;
               case 3:
                    if (Total==Mt[0])
                    {
                    printf("Somme = %g \n", Mt[0]);
                    printf("C'est la bonne facture \n");
                    printf("Il s'agit du Mt 0 \n");
                    }
                    else if (Total==Mt[1])
                    {
                    printf("Somme = %g \n", Mt[1]);
                    printf("C'est la bonne facture \n");
                    printf("Il s'agit du Mt 1 \n");
                    }
                    else if (Total==Mt[2])
                    {
                    printf("Somme = %g \n", Mt[2]);
                    printf("C'est la bonne facture \n");
                    printf("Il s'agit du Mt 2 \n");
                    }
                    else if (Total==Mt[0]+Mt[1])
                    {
                    printf("Somme = %g \n", Mt[0]+Mt[1]);
                    printf("Il est possible d'obtenir le total voulu avec 2 Mts \n");
                    printf("Ce sont les montants 0 et 1 \n");
                    }
                    else if (Total==Mt[0]+Mt[2])
                    {
                    printf("Somme = %g \n", Mt[0]+Mt[2]);
                    printf("Il est possible d'obtenir le total voulu avec 2 Mts \n");
                    printf("Ce sont les montants 0 et 2 \n");
                    }
                    else if (Total==Mt[1]+Mt[2])
                    {
                    printf("Somme = %g \n", Mt[1]+Mt[2]);
                    printf("Il est possible d'obtenir le total voulu avec 2 Mts \n");
                    printf("Ce sont les montants 1 et 2 \n");
                    }
                    else if (Total==Mt[0]+Mt[1]+Mt[2])
                    {
                    printf("Somme = %g \n", Mt[0]+Mt[1]+Mt[2]);
                    printf("Il est possible d'obtenir le total voulu avec 3 Mts \n");
                    printf("Ce sont les montants 1 et 2 et 3\n");
                    }
                    else
                    {
                    printf("Il n'est pas possible de parvenir au total voulu avec ces 3 Mts\n");
                    }
                    break;
                default:
                    printf("Si possible supprimer quelques Mts ne permettant visiblement pas d'atteindre le bon total. \n");
                    printf("La limite de 40 factures a en effet ete depassee\n");
                    break;
            }
     
            // On libère la mémoire allouée avec malloc, on n'en a plus besoin
            free(Mt);
        }
        system("PAUSE");	
        return 0;
    }
    D'avance merci à celui qui saura trouver le problème.

    Salutations,

    Lysen

  2. #2
    Membre expérimenté
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Par défaut
    c'es un probleme "d'arrondie", tous les nombres a virgules ne peuvent être représentés en flottant, par exemple 19.8 sera arrondie en 19.799999.
    c'est une limite du standard, un peut comme 1/3 en base 10.
    cette limite est due a la manière de coder un décimal en binaire.
    essaye donc de trouver un moyen de coder 0.8 en binaire !
    ce n'est tout simplement pas possible:
    0.8 = 1/2 + 1/4 + 1/32 +1/64 + 1/512 +1/1024 + 1/(1024*8)....
    tu n'en verra pas la fin
    une fois arrivé à la limite de la mantisse, on obtiendra 0.799999

    cela dit il me semble qu'il existe des librairies permettant ce type de calcul, ais elles n'utiliseront pas ton copro...donc plus lent !

  3. #3
    Expert confirmé
    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
    Par défaut
    Le problème est lié à la comparaison de deux nombres flottants : les nombres flottants ne représentent les valeurs qu'avec une (bonne, voire très bonne) approximation et seules certaines valeurs sont représentées exactement.

    Pour comparer deux nombres flottants, il convient de vérifier que leur différence est inférieure en valeur absolue à une limite fixée d'après le contexte du problème. Dans ce cas présent, cette limite doit être inférieure à 1 centime et par exemple fixée à 0.001.

    Note : Tu as intérêt à revoir la structure de ton programme, sinon tu n'es pas arrivé au bout pour traiter le cas de 40 factures !

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut
    40 factures, non effectivement, mais le code complet (enfin, jusqu'à 11 factures ) fait déjà 1Mo et 24000 lignes. En fait j'ai fait un autre code de 150 lignes qui me génère mon code de 24'000 lignes en fichier texte, pour chaque cas...
    Ce sont toujours les même lignes, à un indice près, alors je ne me suis pas posé 40 questions.
    Chaque solution implique 6 lignes de codes.
    J'ai remarqué que le nombre de solution correspondait au fameux triangle de Pascal, moins le 1 qui se trouve dans la première colonne.
    Ainsi j'estime que le nombre de lignes nécessaires à une appréciation du montant de 24 factures est d'à peu près 200 millions.
    Si 24'000 lignes de code entrainent un fichier exe de 674 Ko, alors j'ai encore de la marge non ? Ce n'est pas moi qui les tapes, ces lignes de toute façon...

    En revanche, pour la question de l'arrondi, c'est mieux que je le place comment ? Un %.3f ça peut jouer ou cela n'intervient-il que dans l'arrondi visuel ?

  5. #5
    Membre expérimenté
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Par défaut
    %.3f n'arrangera rien
    la solution de diogene semble suffisante dans ton cas.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut
    Voilà merci à tous, j'ai retapé tout ça (pour le cas de 3 montants) et ça fonctionne.
    Je poste le fichier pour de futurs éventuels intéressés.
    Fichiers attachés Fichiers attachés

  7. #7
    Expert confirmé
    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
    Par défaut
    Citation Envoyé par Lysen Voir le message
    40 factures, non effectivement, mais le code complet (enfin, jusqu'à 11 factures ) fait déjà 1Mo et 24000 lignes. En fait j'ai fait un autre code de 150 lignes qui me génère mon code de 24'000 lignes en fichier texte, pour chaque cas...
    Ce sont toujours les même lignes, à un indice près, alors je ne me suis pas posé 40 questions.
    Chaque solution implique 6 lignes de codes.
    J'ai remarqué que le nombre de solution correspondait au fameux triangle de Pascal, moins le 1 qui se trouve dans la première colonne.
    Ainsi j'estime que le nombre de lignes nécessaires à une appréciation du montant de 24 factures est d'à peu près 200 millions.
    Si 24'000 lignes de code entrainent un fichier exe de 674 Ko, alors j'ai encore de la marge non ? Ce n'est pas moi qui les tapes, ces lignes de toute façon...
    Ce n'est vraiment pas une solution sérieuse à ce problème. Une solution correcte aurait sans doute fait au total à peu près 150 lignes.

    En revanche, pour la question de l'arrondi, c'est mieux que je le place comment ? Un %.3f ça peut jouer ou cela n'intervient-il que dans l'arrondi visuel ?
    L'arrondi n'est qu'à l'affichage et n'est que "visuel"

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut
    Certes, ce n'est pas sérieux, mais vu que c'est juste pour dépanner et que je ne suis pas encore suffisamment à l'aise avec les fonctions récurrentes, le seul atout que j'aurais à coder en 150 lignes, c'est que si j'y parviens, alors je ne serais plus dans une situation où 40 factures représentent une limite impossible à atteindre

    Mais si quelqu'un dispose d'une idée pour faire rétrécir mon code, je prends, parce que j'entame en ce moment les 6 millions de lignes et mon PC commence à avoir des petits problèmes de mémoire.

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

Discussions similaires

  1. [Tableaux] Message erreur: undefined variable
    Par arti2004 dans le forum Langage
    Réponses: 9
    Dernier message: 23/05/2006, 14h31
  2. [VBA-E]erreur 91: variable objet ou variable de bloc With...
    Par cdk dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/03/2006, 14h19
  3. erreur de variable
    Par bobic dans le forum ASP
    Réponses: 8
    Dernier message: 15/11/2005, 11h20
  4. erreur déclaration variables
    Par bobic dans le forum ASP
    Réponses: 4
    Dernier message: 13/09/2005, 10h11
  5. Réponses: 1
    Dernier message: 19/08/2005, 12h33

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