[résolu] langage C - problème de modulo

Salut à tous,

J'ai un problème bizarre sur un arduino pro mega. Le modulo ne donne pas les bons résultats.

for (int p = 0; p < NBR_TOUCHES_TOTAL; p++)
    {
        note = p % NBR_TOUCHEPARCLAV;

        Serial.print("p = ");
        Serial.print(p);
        Serial.print("\t NBR_TOUCHEPARCLAV = ");
        Serial.print(NBR_TOUCHEPARCLAV);
        Serial.print("\t p%NBR_TOUCHEPARCLAV = ");
        Serial.println(p % NBR_TOUCHEPARCLAV);        
        delay(2000);

Le résultat :

p = 0 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 0
p = 1 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 8
p = 2 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 16
p = 3 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 24
p = 4 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 32
p = 5 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 40
p = 6 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 48
p = 7 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 56
p = 8 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 0
p = 9 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 8
p = 10 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 16
p = 11 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 24
p = 12 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 32
p = 13 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 40
p = 14 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 48
p = 15 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 56
p = 16 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 0
p = 17 NBR_TOUCHEPARCLAV = 64 p%NBR_TOUCHEPARCLAV = 8

Je suis peut-être fatigué, mais rassurez moi, c'est résultats sont bien faux ???

Merci d'avance pour votre aide :blush:

EDIT : d'ailleurs, le code suivant me donne bien les bons résultats :

   for(int i = 0; i < 64; i++)
        Serial.println(i % 64);

Le résultat est faux

Comment est défini NBR_TOUCHEPARCLAV?

Lorsque je mets : int n = p % 64; au lieu de int n = p % NBR_TOUCHEPARCLAV ça fonctionne.

Pourtant sa valeur est bonne, on le voit bien dans le print.

Cette variable est déclarrée comme ça :

#define NBR_ENTREES                 8
#define NBR_SORTIES_PAR_CLAVIERS    8
#define NBR_TOUCHEPARCLAV           NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS

Question : le modulo ne fonctionne pas avec des constantes définies dans le preprocesseur ?

vohu:

#define NBR_ENTREES                 8

#define NBR_SORTIES_PAR_CLAVIERS    8
#define NBR_TOUCHEPARCLAV           NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS




Question : le modulo ne fonctionne pas avec des constantes définies dans le preprocesseur ?

Il faut mettre des parenthèses

#define NBR_TOUCHEPARCLAV          (NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS)

Sans les parenthèses le modulo est calculé avec NBR_ENTREES et le résultat multiplié par NBR_SORTIES_PAR_CLAVIERS

Haaaaaaaaaaaa,

Et il faut mettre entre parenthèses tous calculs se trouvant dans un #define ?
Je pense que pour les additions soustractions ça marche sans, mais il est préférable de les mettre quand même ?

Il ne faut pas oublier que les formules sont évaluées de la gauche vers la droite et que certains opérateurs sont prioritaires sur d'autres.

Tu aurais rencontré le même problème si tu avais écrit la formule directement sans passer par un define en oubliant les parenthèses.

j'avoue ne pas comprendre.

si j'avais fait :

nbr = NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS

Je n'aurai pas le bon résultat ?

Je pensais que * avait une priorité plus haute ?

Le problème c'est le modulo il a la même priorité que la multiplication

Dans ton code tu as ça

#define NBR_TOUCHEPARCLAV           NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS

p % NBR_TOUCHEPARCLAV

Le pré-processeur génère ça:

p % NBR_ENTREES * NBR_SORTIES_PAR_CLAVIERS

L'interprétation se faisant de la gauche vers la droite
tu calcules
p % NBR_ENTREES
puis le résultat est multiplié par NBR_SORTIES_PAR_CLAVIERS

OK ! Merci pour l'explication

Ca faisait des heures que je m'arrachais les cheveux avec ce truc :smiling_imp: