Petit détail différence 2.12345 et 2,12345

j'avais besoin d'une variable multipliée par un nombre 2,567 auquel j 'ajoutais une autre valeur : x = y * 2,567 +12 dans mon code, j'avais par mégarde fait : x = y * 2.567 + 12, un point au lieu de la virgule. Aucun problème à la compilation, mais résultat faux. J' ai cherché pendant un certain temps pourquoi cela ne fonctionnait pas. j'ai trouvé, mais je ne comprends pas pourquoi 2.567 est accepté comme nombre et me donne 0 en résultat.

en C++ on écrit avec la notation anglaise, donc les nombre sont notés avec un point décimal et pas une virgule.

il faut donc vraiment écrire x = y * 2.567 + 12; et bien sûr il faut que x soit de type float ou double.

void setup() {
  Serial.begin(115200);
  float y = 10.5;
  float x = y * 2.567 + 12;
  Serial.print("y = "); Serial.println(y);    // affichage avec 2 chiffres après la virgule par défaut
  Serial.print("x = "); Serial.println(x, 5); // affichage avec 5 chiffres après la virgule
}

void loop() {}

Vous devriez voir dans le moniteur série (ouvert à 115200 bauds)

y = 10.50
x = 38.95350

Si vous avez 0 comme résultat, c'est que soit ça fait vraiment 0, soit vous avez un bug dans le code que vous ne nous avez pas montré.

Un bout du code simplifié sur un autre PC:
Serial.print("Vitesse1 (nb_pas/sec): ");
resu = 0.04 * valeur_Pot ; //
Serial.print(" -->RESU: ");
Serial.println(resu);

        Serial.print("Vitesse1 (nb_pas/sec): ");
        resu = 0,04 * valeur_Pot ;  //
        Serial.print("  -->RESU: ");
        Serial.println(resu);
        vitess= 20 - resu ;

les 4 premières lignes ok sans fautes, le 2 ème bout avec l'erreur j'ai mis une virgule 0,04 au lieu de 0. 04 et à la compil même sur ce pc rien que le petit bout OK sans erreur alors que la virgule est bien là. Je cherche encore

La virgule est un séparateur d'instruction que l'on utilise si on veut du code illisible par exemple. en écrivant resu = 0,04 * valeur_Pot ; // la compilation donne deux instructions comme si on avait mis:

resu = 0;
04 * valeur_Pot ;  //

Il met 0.00 dans resu. avant ou après, il calcule 4 * valeur_Pot qu'il ne range nulle part. Il ne donne pas d'erreur, mais il pourrait donner un avertissement.

je savais que c'était un point pour séparer unité décimal, mais pour la virgule je ne savais pas et même pas un avertissement, il donne 0 comme résultat. Une re lecture de 2H pour trouver. Pour un début après basic turbo pascal ASM java, il faut encore apprendre

Dans les préférences
=> Avertissements du Compilateur: Tout à la place de par Défaut
Et tu auras un warning

~~Non, ~~En C++, l’opérateur virgule (qui n’est pas le séparateur décimal) est un opérateur binaire qui évalue d’abord la première expression, puis retourne la seconde. (Cf la spec du Built-in comma operator)

Ici 0 est évalué et ignoré, puis 04 est interprété comme un entier en notation octale (valeur 4 en base 10). Donc l’expression reste correcte numériquement et resu vaudra 4 x valeur_pot. Si ça fait 0 c’est que valeur_pot valait 0 ou que resu est un entier et valeur_pot un float plus petit que 0.25

Bonsoir,

@J-M-L C'est rare (voire très rare) que l'on puisse te prendre en défaut, mais comme ',' est moins prioritaire que '=', l'expression sera évaluée comme le dit @vileroi
d'abord resu = 0
puis 04 * valeur_Pot
donc resu vaut 0

Effectivement @vileroi a tout à fait raison, je n’avais pas pensé à l’affectation, j’avais en tête l’expression juste à droite mais l’affectation change tout en effet.

Si on avait mis des parenthèses alors on aurait pris la seconde valeur

resu = (0,04 * valeur_Pot) ;

Car la priorité changeait.

Mea culpa

A noter que si on avait écrit

float resu = 0,04 * valeur_Pot ;

La compilation aurait planté car ce n’aurait pas été l’opérateur virgule qui était attendu mais la séparation entre définition de variables.

La différence est minime pour moi je reprends mes cours de maths :
resu = (0,04 * valeur_Pot) et resu = 0,04 * valeur_Pot c'est identique.
Ce que j' ai pas compris c'est la différence entre 0, 04 et 0 .04 qui soit accepté par le compilateur et donne la valeur 0 en résultat , c'est . ou , le compilateur devrait signaler qu'il y a ambiguïté. C'est vrai que je débute en C, mais après basic, turbo pascal, Asm(68HC11) , java mon dernier métier, j'apprends encore et je m'amuse et j'espère qu'il n'y pas d'autres ambiguïtés car pour le moment cela reste de la logique.

Pour le compilateur il n’y a pas d’ambiguïté vous demandez de faire quelque chose qui est autorisé, en respectant la syntaxe et grammaire du langage.

L’ambiguïté est dans votre tête par méconnaissance du langage . Le séparateur pour les décimales a toujours été le point et vous ne connaissiez pas l’opérateur virgule qui sépare deux expressions….

Si vous activez les warning (toujours une bonne idée) vous en aurez un car le compilateur verra une instruction qui ne sert à rien quand vous mettez la virgule donc vous signalera cela - mais pas d’ambiguïté.


Pour vous oui mais pas pour le compilateur :slight_smile:

Avec les parenthèse vous précisez l’ordre dans lequel les expressions doivent être évaluées. Vous dite au compilateur «affectez le résultat de l’évaluation de ce qui est entre parenthèses à la variable resu ». Donc le compilateur fait l’évaluation. Il voit deux expressions séparées par une virgule. La norme dit dans ce cas que le compilateur évalue l’expression de gauche et ignore le résultat puis évalué l’expression de droite et retourne cette valeur. C’est donc la partie de droite qui va aller dans resu.

Sans les parenthèses le compilateur voit aussi deux expressions séparées par une virgule. Il évalue donc celle de gauche resu = 0 qui a pour effet de bord d’affecter la variable et retourne cette valeur 0 qui est ignorée. Puis il évalue l’expression de droite 04 * valeur_Pot et retourne cette valeur mais personne n’en fait rien (d’où le warning qu’il y a une expression inutile).

C’est pour cela que dans un cas vous avez 0 et dans l’autre 4 x valeur_pot mais dans aucun cas la virgule sera vue comme un point décimal.

Notez aussi que 04 est une écriture en base 8 (octal) et ça vaut 4 mais si vous aviez écrit 08 ça n’existe pas (en base 8 les symboles vont de 0 à 7) et le compilateur aurait mis une erreur.

belle explication , on apprend tous les jours , merci, c'est vrai le C n'est pas encore mon langage habituel, j'ai encore beaucoup de détails à apprendre malgré ma documentation

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.