[Résolu] Calculs simples sur MEGA 2560 non corrects.

Bonjour,

Je viens de réaliser un petit programme de quelques lignes et je m'aperçois que des calculs simples
ne sont pas corrects. J'ai réduit au maximum jusqu'à obtenir :

Serial.print("3/2 = ");
float u_instant = 3/2;
Serial.print(u_instant);
Serial.println(" V");

Serial.print("5/1024*(zzz-512)");
u_instant = 5/1024*(zzz-512); // zzz valeur quelconque > 0
Serial.print(u_instant);
Serial.println(" V");

réponse : 3/2 = 1.00 V pour le 1er

réponse : 5/1024*(zzz-512) = 0.00 V pour le 2éme

Que se passe-t'il ? Manque une librairie ? (je n'ai aucun #include dans mon cas)
Je ne peux plus m'arracher les cheveux, il n'en reste plus.

Merci à tous

En C, le type du résultat ne dépend pas de la destination (float), mais des "participants" (des int). Comme tu as écrits des entiers, la division est entière.

Il faut qu'au moins un des éléments soit converti en float, via un (float) ou en le notant avec une virgule , pour que la division en virgule flottante s'applique.

Salut,
pour être exact les calculs sont corrects, c'est juste que ce ne sont pas ceux que tu t'attendais à recevoir. En fait les deux opérandes de tes divisions sont des entiers, donc le compilateur génère une division entière (même s'il stocke ensuite le résultat des un float comme tu le lui as demandé).

Pour faire une division en virgule flottante le plus simple est que l'un au moins des opérandes soit un flottant, ce qui revient à écrire :

float u_instant = 3 / 2.0;

Pareil pour l'autre exemple.

Note: Il serait suffisant d'écrire 2. à la place de 2.0, mais c'est sans doute moins lisible, surtout lorsque l'on débute.

Grillé XD

Affaire réglée, ça fonctionne !

Je ne me souviens pas avoir lu cela dans les tutos mais je ne suis pas prêt de l'oublier.

Merci à tous
Géryko

autre problème que je n'avais pas vu :

dans u_instant = 4,85/1024*(zzz-512);

si zzz < 512 le calcul est faux exemple pour zzz = 337 résultat = 309.57 V

Géryko

Bonjour,
Essaye
u_instant = 4.85/1024*float(zzz-512);

Bonjour icare

Non ça ne fonctionne toujours pas.
exemple : pour zzz = 295 ----- > 309.37 V

Par contre j'avais oublié de préciser que lorsque je lis zzz dans un tableau (int) la formule fonctionne.
J'extrais comme ceci :

int zzz = tableau [ x ];

Géryko

Et ça ?

u_instant = 4.85/1024*(zzz-512.0);

Boujour B@tto,

Oui, ta solution fonctionne également.

Entre temps, j'ai modifié mon post précédent . (en rouge)
et j'avais trouvé une autre solution équivalente en transformant mon zzz int en zzz float.
ce qui revient au même.

Ce que je ne comprends plus :
Lorsque je lis : int zzz dans mon tableau lui même int, là ça fonctionne. Mystère !
u_instant = 4,85/1024*(zzz-512); est OK même si zzz < 512

Pas évident cette affaire ! (Je le note quand même Résolu mais si qq a des présicions ....)
Merci à tous
Géryko

Bonjour pepe,

Mon IDE Arduino est 1.0.5-r2 je suis débutant, je l'ai téléchargé en août 2014.

Pour venir à bout de ce problème j'ai tellement modifié mon programme qu'il est maintenant à remettre en état.

L'exercice consistait à lire une tension alternative sur le port A0.
Pour tester j'avais 2 possibilités : (2 options dans mon programme)

a) Une mesure unique (mono coup) word valeur lue lecture_Ua à tranformer en volts. (Unsigned)
Serial.print("4.85/1024*(lecture_Ua-512)");
Dans ce cas il faut impérativement mettre lecture_Ua en float OU écrire 512.0. ( lecture_Ua < 512 ne fonctionne pas)
Le résultat correspond à ton calcul décrit ci-dessus.

b) Une boucle de lecture (350 lectures maxi)
où je lis 2 périodes 50Hz (échantilonnage 125us = 8kHz) théoriquement 320 échantillons
Je place les valeurs lues dans un tableau int et je lis le tableau à la fin.
Dans ce cas ce n'est pas nécessaire de mettre zzz float ! Bizarre.

Géryko
en rouge : corrections

Re,
J'ai l'impression que tu mélanges les points et les virgules dans les nombres réels.

Pour icare :
Sauf erreur qui peut toujours arriver, je ne mélange pas les points et les virgules dans les nombres réels.
D'ailleurs je ne manipule que des variables donc je ne vois pas.

Pour pepe :
Autant pour moi, mon message précédent comporte une erreur.
J'ai corrigé mon message précédent en rouge. Je ne sais pas si j'ai bien fait ?

Ma variable de lecture A0 est word (0 à 65535) j'aurais mieux fait de mettre unsigned int
Les autres variables zzz et le tableau sont int sans précision donc -32 768 à +32 767

en résumé je crois avoir compris :

  1. lecture sur A0 (unsigned) - 512 ne fonctionne pas même si A0 (unsigned) > 0 et < 512
  2. lorsque je mets la valeur lue sur A0 (unsigned) dans mon tableau int
    et que je la reprends zzz , int zzz - 512 c'est correct.

Sauf erreur de ma part, nous en resterons là. Je ne veux pas abuser de votre bonne volonté.
Bien à vous
Géryko