J'ai un (petit) problème de calcul sur du float que je n'arrive pas ni à résoudre, ni à comprendre. Voila le problème:
J'ai une fonction avec juste cette partie qui pose problème:
float compensation;
compensation = (0,021 * 361);
Serial.println(" --- entrée entrée de fonction ---");
Serial.print("compensation = ");
Serial.println(compensation);
Si j'exécute ça, la sortie sur la console me donne
--- entrée entrée de fonction ---
compensation = 6137.00
Ce n'est pas tout à fait le résultat auquel je m'attend...
Pensant à un problème sur la valeur 361 qui pourrait forcer le calcul en "int", j'ai tenté ça:
Quand le. Compilateur rencontre (0,021 * 361.0) il voit deux expressions séparées par l’opérateur virgule.
La première expression 0 est évaluée et ne fait rien donc l’optimiseur va la dégager.
Il reste (021 * 361.0). En C ou C++ quand on note un nombre en commençant par 0 ça veut dire qu’il est exprimé est octal (base 8) donc 021 c’est 17 en décimal. Le compilateur calcule donc 17x361=6137 donc la valeur que vous voyez est bonne
La bonne notation
const float compensation = 0.021 * 361.0; // ici un commentaire explicatif sur les valeurs
@J-M-L@philippe86220
Merci à vous deux.
J'étais persuadé que c'était la virgule, et je n'ai vraiment pas pensé à ça!!!!
Et le compilateur n'a rien dit, bien sur.
Je peux confirmer que ça marche mieux en plus.... Et si je vous dit que la compilation est plus rapide, vous me croyez? ou c'est moi qui yoyote?
En tout cas, merci encore.
le compilateur me prévient que je fais sans doute une erreur
sketch_nov06a.ino: In function 'void setup()':
sketch_nov06a.ino:4:28: warning: left operand of comma operator has no effect [-Wunused-value]
compensation = (0,021 * 361.0);
^~~~~
si vous compilez pour ESP32 ce sera même traité comme une erreur et la compilation va s'arrêter.
et si vous indentez le code vous verrez que l'écriture se transforme en
compensation = (0, 021 * 361.0);
montrant bien avec un espace qu'il y a sans doute un souci à ce niveau
Le mot clé constexpr indique au compilateur qu’une variable (ou fonction) peut déjà être évaluée pendant la compilation et non plus seulement à l’exécution du programme. L’avantage c’est que le compilateur effectue le travail une fois pour toutes, ce qui rend l’exécution du programme plus rapide.
En déclarant des constantes avec constexpr, on les rend utilisables à la compilation :
Le qualificatif constexpr indique que la donnée qualifiée est constante, ce qui permet de l'utiliser dans une expression à résultat constant. Comme dit plus haut, Le compilateur précalcule le résultat à des fins d'optimisation.
En fait les variables déclarées constexpr ont un statut semblable à celui des littéraux (tels que les constantes numériques). Toutefois contrairement aux littéraux, elles résident en mémoire : on peut donc obtenir leur adresse. Elles doivent être des données de types primitifs (int, double, pointeurs ...) ou des agrégats composés de données de types primitifs. Elles peuvent aussi être des objets, à condition que la classe correspondante ait un constructeur également déclaré constexpr.
Implicitement, utiliser constexpr sur une variable revient à la déclarer const, ce qui est logique. Dans le but d'être explicite, on peut préciser également const mais ce n'est pas une obligation :