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 :

Faire une moyenne d'un tableau de chiffres


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut Faire une moyenne d'un tableau de chiffres
    Bonjour,

    Je cherche à calculer la moyenne de 10 valeurs contenus dans un tableau de chiffre de 'unsigned short int'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    unsigned short long average_ADC_int[10] = 0;
    unsigned short long sum_ADC_int = 0;
    unsigned long averaged_ADC_int = 0;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        sum_ADC_int = 0;
     
        for (int i=0; i<10; i++)                      
            {
            ADC_int = ADC_read();                 // Collecte la valeur ADC et stockage dans le tableau
            average_ADC_int[i] = ADC_int;
     
            sum_ADC_int += average_ADC_int[i];
            __delay_ms(20);                        // Prochaine mesure dans 20ms
            }
        averaged_ADC_int = (sum_ADC_int/10);
    En procédant ainsi la somme des 10 valeurs est erronée, et de ce fait la moyenne aussi.
    Pouvez vous me dire ce qui ne va pas svp ?

    Merci à vous,

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Citation Envoyé par lcoulon Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    unsigned short long average_ADC_int[10] = 0;
    unsigned short long sum_ADC_int = 0;
    unsigned long averaged_ADC_int = 0;
    Heuuu.... unsigned short long ..... ??? Tu es sur de toi là ?
    Soit c'est l'un, soit c'est l'autre, mais ce n'est pas les deux ! Ce n'est même pas censé pouvoir compiler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        sum_ADC_int = 0;
     
        for (int i=0; i<10; i++)                      
            {
            ADC_int = ADC_read();                 // Collecte la valeur ADC et stockage dans le tableau
            average_ADC_int[i] = ADC_int;
     
            sum_ADC_int += average_ADC_int[i];
            __delay_ms(20);                        // Prochaine mesure dans 20ms
            }
        averaged_ADC_int = (sum_ADC_int/10);
    Tu pourrais te passer de la variable ADC_int, et mettre directement ADC_read() dans ton average_ADC_int[i]. (dans le code présenté, en tout cas)

    (Je pars du principe que tu as consciemment mis le résultat de ta moyenne dans un long. Si ce n'est pas le cas, attention à la perte d'information sur la division !)
    Comme ça, cela me semble correct. As-tu déjà fait un coup de debog ? A coup de printf(), voir de débogueur intégré (ou non) à un ide, pour voir l'état du tableau à chaque tour de boucle ?

  3. #3
    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
    Heuuu.... unsigned short long ..... ??? Tu es sur de toi là ?
    Soit c'est l'un, soit c'est l'autre, mais ce n'est pas les deux ! Ce n'est même pas censé pouvoir compiler.
    Et pourtant ça existe Ce n'est pas standard, certes, mais certains compilateurs le proposent. Par exemple, C18 de Microchip propose short long et long short. Les deux types sont équivalents et sont sur 24 bits.

    @lcoulon : pourquoi stocker la somme dans un short long et la moyenne dans un long ?? Tu devrais au moins faire l'inverse, tu as moins de chances d'avoir un overflow lors de la somme.

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    En effet, j'utilise XC8 de Microchip, l'evolution de C18.

    Mon tableau "average_ADC_int" se rempli bien a tour de boucle avec des valeurs:

    1701098
    1701099
    1701102
    1701098
    1701130
    1701116
    1701140
    1701099
    1701103
    1701110

    Cependant, le resultat "sum_ADC_int" est : 11907783
    alors qu'il etre : 17011095

    le result de "averaged_ADC_int" n'est également pas celui attendu : 23388

    Je ne sais pas pourquoi les résultats sont faux.

  5. #5
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    En déclarant les variables ainsi, le résultat s'approche de la réalité à +- 4 près

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned short long average_ADC_int[10] = 0;
    unsigned long sum_ADC_int = 0;
    unsigned short long averaged_ADC_int = 0;
    Le fait de déclarer le résultat en short long plutôt qu'en float évite un résultat à virgule, mais cela peut-il générer un mauvais résultat ou bien le résultat est automatiquement arrondi puisque stocké dans un short long ?

  6. #6
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2012
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Septembre 2012
    Messages : 170
    Points : 234
    Points
    234
    Par défaut
    Bonjour,pourrais ton connaitre le type retourné par la fonction ADC_read() ainsi que celui de ADC_int (où tu stock la valeur retournée par la fonction)? Tu utilises des variables sans les déclarer?
    Tu peux commencer par te débarrasser de la variable et vérifier le type retourné,ce serait un bon début!
    Ensuite passer aux types de tes variables sum et avg.
    Bon courage!

  7. #7
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned short long ADC_read(void);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned short long ADC_int;                  // ADC 24 bits value from ADC converter
    En fait si je ne passe pas par une variable intermédiaire, et procède ainsi, le compileur refuse la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     average_ADC_int[i] = ADC_read();
    error: (712) can't generate code for this expression

  8. #8
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Ah ... La remarque de johnlobs m'a fait penser a vérifier le contenu de ma fonction ADC_read();
    Celle ci doit retourner un 'short long' mais je viens de m’apercevoir que la variable retournée était quant à elle, déclarée comme 'long'

    Je viens de modifier le contenu de la fonction pour la variable retournée et le type de la fonction soient toutes les deux des 'long'

    A présent , le compilateur accepte ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        for (int i=0; i<10; i++)
            {
            average_ADC_int[i] = ADC_read();
            sum_ADC_int += average_ADC_int[i];
            __delay_ms(20);
            }
        averaged_ADC_int = (sum_ADC_int/10);
    Pour autant, lors d'un nouvel essai en mode debug avec un tableau rempli avec les valeurs suivantes :

    1700343
    1700336
    1700330
    1700326
    1700322
    1700331
    1700343
    1700321
    1700326
    1700332

    Je trouve sum_ADC_int = 1700343 ( l'affichage de cette valeur bug dans car il semble manquer un chiffre ) au lieu de 17003310
    et average_ADC_int = 1700329 au lieu de 1700331

  9. #9
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2012
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Septembre 2012
    Messages : 170
    Points : 234
    Points
    234
    Par défaut
    Bonjour,
    Essaye d’homogénéiser tes types et de prendre le soin d'utiliser les types adéquats.
    Si j'ai bien compris ton message:
    Je viens de modifier le contenu de la fonction pour la variable retournée et le type de la fonction soient toutes les deux des 'long
    C'est OK! mais par contre il me semble que tu récupères la valeur retournée par ta fonction dans un tableau de unsigned short long!!!

    Par contre je dois être rassuré par rapport à un truc:le tableau est fait pour avoir un historique des mesures?? parce que sinon le tableau ne sert a rien d'autre dans ta boucle et tu as un risque de dépassement tampon(sait on jamais).
    Je dis ça parce que je vois une initialisation bizarre j'aimerais bien la comprendre si possible:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned short long average_ADC_int[10] = 0;
    Est tu toujours dans la zone memoire qui est affectée a ton tableau ou est tu dans une autre zone qui ne t'appartient pas???

    Merci et bon courage!

  10. #10
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Est-ce que tu as bien inclus le header qui déclare ADC_read() ? Parce qu'en C quand on appelle un fonction non déclarée, le compilo suppose qu'elle retourne un int. Mais si elle ne retourne pas quelque chose qui fait la taille d'un int, tu ne vas pas récupérer la bonne valeur.

Discussions similaires

  1. [SQL] faire une moyenne : PHP ou SQL ?
    Par [Hugo] dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 17/10/2007, 19h30
  2. [MySQL] Pagination : faire une boucle dans un tableau ?
    Par benjam89 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 13/09/2007, 20h10
  3. Faire une moyenne en ignorant les valeurs nulles
    Par Giansolo dans le forum MATLAB
    Réponses: 2
    Dernier message: 08/06/2007, 14h38
  4. [VBA-E]Excel / Faire une moyenne après un tri
    Par marcobosio dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/03/2007, 20h54
  5. Faire une moyenne en excluant les 0
    Par Lag dans le forum Access
    Réponses: 12
    Dernier message: 06/09/2005, 18h25

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