Bon,
utiliser un int16_t au lieu d'un float mange .... deux octets supplémentaires. Ca reste frugal.
Les temps d'execution sont peut être un peu plus longs avec des floats.....
A priori , multiplier deux int16_t mange 4 multiplications sur 8 bits, 3 additions.
multiplier deux floats (estimation naîve) mange 9 multiplications sur 8 bits, 9 additions (+ un recadrage).
Vous utilisez déjà une variable de type float. Donc l'espace de stockage est déjà réservé.
Que l'opération soit plus longue est une autre histoire. Mais si l'on parle de stockage et uniquement de stockage, il est identique dans les deux cas.
normal vu que j'attend une valeur avec décimale.
c'est pour le
int M=53;
ClarkGaybeul:
Vous utilisez déjà une variable de type float. Donc l'espace de stockage est déjà réservé.
Que l'opération soit plus longue est une autre histoire. Mais si l'on parle de stockage et uniquement de stockage, il est identique dans les deux cas.
Le croquis utilise 2522 octets (8%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 184 octets (8%) de mémoire dynamique, ce qui laisse 1864 octets pour les variables locales. Le maximum est de 2048 octets.
a=((H*60)+M)/60.0;
Le croquis utilise 2522 octets (8%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 184 octets (8%) de mémoire dynamique, ce qui laisse 1864 octets pour les variables locales. Le maximum est de 2048 octets.
Il faut savoir que l'espace de stockage ne se réduit pas à la FLASH et la RAM.
Il y a aussi des registres, et le compilateur les utilise en priorité.
Le compilateur reporte ce qu'il est capable de calculer. Le 60.0 est dynamique pas alloué dans une variable.
Ensuite attention aux phase d'optimisation si le compilateur peut calculer pour vous à la compilation. Il faut introduire de la confusion
Sur un MEGA avec
int H, M;
float a;
void setup()
{
Serial.begin(115200);
H = random(0, 24);
M = random(0, 60);
a = ((H * 60) + M) / 60;
Serial.println(a);
}
void loop() {}
On obtient:
[size=8pt]Le croquis utilise [b][color=green]3738[/color][/b] octets (1%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent [b]206[/b] octets (2%) de mémoire dynamique, ce qui laisse 7986 octets pour les variables locales. Le maximum est de 8192 octets.[/size]
alors qu'avec:
int H, M;
float a;
void setup()
{
Serial.begin(115200);
H = random(0, 24);
M = random(0, 60);
a = ((H * 60) + M) / 60.0; // 60.0 force la seconde partie du calcul en flottant
Serial.println(a);
}
void loop() {}
[size=8pt]Le croquis utilise [b][color=red]3870[/color][/b] octets (1%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent [b]206[/b] octets (2%) de mémoire dynamique, ce qui laisse 7986 octets pour les variables locales. Le maximum est de 8192 octets.[/size]
--> On voit que plus de place a été alloué en SRAM dans le cas où on force le calcul en flottant mais la taille allouée pour les variables globales est restée identique puisque le 60 ou 60.0 sont dynamiquement insérés dans le code.
Oui, mais si vous en êtes réduit à rabioter pour deux octets (soit 1 pour mille), vous êtes très proche de la saturation de votre RAM(et frôlez un dysfonctionnement)
Ce qui est bien plus gênant, c'est que, dès que vous utiliser -et surtout imprimez- des floats, comme JML l'a signalé, vous utilisez pas mal de flash : de mémoire, c'est un ou 2 K pour une librairie bien écrite, et, pour l'impression, 2 ou 4 k. Sur 32 K de flash, c'est au mieux 5% ....(cinquante fois plus qu'un float par ci par là)...
Même avec ça, le confort induit par l'usage de floats est plus agréable que de pifomètrer les bornes des variables, et en déduire leur type exact.... (vous pourriez multiplier M par 100 oi 1000 -unsigned int uint16_t- et faire vos calculs en 100 -ièmes- millièmes d'entiers : ça serait dur à écrire et à lire; avec une marge de 5-10%, ça ne vaut pas le coup pour un avr328 -ou supérieur-)
dbrion06: @JML:
dans un post plein de bon sens, vous avez introduit s:faut:peut:
(la confusion vient tout naturellement, pas besoin de l'aider)
LOL
Ce que je veux dire c'est qu'il faut que le calcul ne soit pas évident pour le pré-processeur
Si j'avais alloué H et M statiquement avec une valeur, alors le pré-processeur aurait fait le calcul pour moi et n'aurait pas généré de code.
Si vous regardez cela (sans la fonction random):
int H, M;
float a;
void setup()
{
Serial.begin(115200);
H = 20;
M = 30;
a = ((H * 60) + M) / 60.0; // 60.0 force la seconde partie du calcul en flottant
Serial.println(a);
}
void loop() {}
[size=8pt]Le croquis utilise [b][color=purple]2812[/color][/b] octets (1%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent [b][color=purple]188[/color][/b] octets (2%) de mémoire dynamique, ce qui laisse 8004 octets pour les variables locales. Le maximum est de 8192 octets.[/size]
On voit que la SRAM et la FLASH ne sont plus du tout encombrées. En pratique le pré-processeur a tout viré et probablement affecté juste le résultat du calcul directement dans le print().
Je vais vous sembler un affreux pinailleur, mais c'est l'optimiseur qui vire avec une ardeur parfois déroutante tout ce qui prend de la place.
A ma connaissance, arduino a 2 préprocesseurs, l'un, spécifique a Arduino, pour remettre les fonctions dans l'ordre (ou faire croire qu'elles sont déclarées dans l'ordre) et exploiter les #include et le preprocesseur C: mais il n'a qu'un optimiseur.
Les variables globales utilisent 188 octets (2%) de mémoire dynamique.
Oui et j'obtiens personnellement 184 (IDE 1.8.5).
En pratique le pré-processeur a tout viré et probablement affecté juste le résultat du calcul directement dans le print().
Pas le préproc, plutôt le compilateur (optimisation)
Pour trancher et savoir ce qui se passe effectivement (utilisation des registres ou de la pile), il faudrait demander au compilateur de générer l'assembleur.
Un canon pour tuer une mouche dans le cas qui nous occupe.
Dans l'IDE ARDUINO, les outils mis à disposition ne permettent pas une investigation très poussée.
Sauf erreur de ma part (veuillez m'excuser, je connais mieux les compilateurs utilisés en ligne de commande avec Makefile ou CMake) L'IDE ne permet pas non plus de paramétrer l'optimisation, ce qui est souvent indispensable lorsque l'on utilise un débogueur. Mais comme il n'y a pas de débogueur dans l'IDE, cela ne pose pas de problème.
avr-gcc possède ces options :
-O<number> Set optimization level to <number>
-Ofast Optimize for speed disregarding exact standards
compliance
-Og Optimize for debugging experience rather than
speed or size
-Os Optimize for space rather than speed
Il faut savoir que l'espace de stockage ne se réduit pas à la FLASH et la RAM.
Il y a aussi des registres, et le compilateur les utilise en priorité.
J'ajouterai - oubli impardonnable de ma part - la pile.
Désolé de vous quitter mais je suis enseignant et très occupé.