Je travaille avec une nano 33 - 32 bits - avec des variables de type double.
j'effectue des calculs dont j'affiche le résultat arrondi à 7 chiffres après la virgule.
Lorsque le résultat présente un nombre décimal dont le nombre de chiffres est inférieur ou égal à 7 je souhaite récupérer le nombre de chiffres après la virgule.
Par exemple si je divise 45.256 par 2, le résultat est 22.6280000. Je voudrai pouvoir récupérer le nombre de chiffres après la virgule, c'est à dire 3.
Savez-vous si il existe une fonction pour faire ça ?
il n'existe pas de fonction à ma connaissance mais vous pouvez l'écrire. vous convertissez votre double en chaîne (fonction dtostrf()) avec 7 chiffres après la Virgule puis vous comptez le nombre de 0 ininterrompus depuis la fin de la chaîne (on connait l'index avec strlen() - 1) jusqu'au point décimal
J'ai trouver que sur la nano 33 il fallait : #include <avr/dtostrf.h>
Je pense que c'est ça que vous évoquez :
#include <avr/dtostrf.h>
const double MonChiffre = 45.25 ;
char z[20];
byte nb = 0;
byte NombreChiffreApresVirgule = 0;
void setup() {
Serial.begin(57600);
}
void loop() {
//Serial.println(MonChiffre,7);
dtostrf(MonChiffre,6,7,z);
for (byte f = 0; f <= (strlen(z)); f++)
{
if (z[f] =='0') nb = nb + 1;
}
NombreChiffreApresVirgule = 7 - nb;
Serial.println(NombreChiffreApresVirgule);
nb=0;
NombreChiffreApresVirgule = 0;
delay(5000);
}
La variable NombreChiffreApresVirgule m'indique bien ce que je voulais.
Par contre, je ne comprends pas trop bien à quoi sert le deuxième paramètre de la fonction dtostrf (j'ai mis 6 au hasard), il semble que ce soit pour définir la largeur de la variable de sortie ou le nombre de chiffres mais c'est un paramètre que je ne peux pas connaitre à l'avance.
largeur min, mettez 0 (sinon ça rajoute des espaces si vous avez un petit nombre)
nb_chiffres_après_la_virgule c'est 7
il faut que le buffer soit assez grand pour votre plus grand nombre et avec une case en plus pour le caractère nul à la fin
ensuite votre fonction ne va pas bien, vous comptez le nombre de '0' mais si mon nombre c'est 100.0001000 vous voyez bien que ça ne va pas fonctionner (et si la longueur donnée par strlen c'est 5 il faut lire les caractère jusqu'à 4 au plus, pas prendre le caractère à l'indice 5 - ce sera le '\0' qui marque la fin de chaîne)
il faut partir de la droite et compter le nombre de 0 jusqu'à ce que vous rencontriez quelque chose de différent de '0' (vous tomberez sur le '.' point décimal ou un chiffre)
Bon, je dois aller au restaurant et demain matin je me lève à 04h00 pour essayer de photographier le brame du cerf...
Je m'y remettrai demain d'autant plus que madame trouve que je passe trop de temps sur mon ordinateur.
dtostrf(MonChiffre,0,7,z);
for ( int f = (strlen(z)-1); f >= 0; f--)
{
if (z[f] == '0')
{
nb = nb + 1;
}
else
{
break;
}
NombreChiffreApresVirgule = 7 - nb;
Pour moi, j'ai bien le bon nombre de chiffres après la virgule. J'ai bien ce que je voulais.
Dans une boucle for, le deuxième paramètre fixe la limite de l'itération mais lorsque j'utilise :
for ( int f = (strlen(z)-1); f == 0; f--)
il n'y a pas d'itération si bien que ma variable "n" n'est pas incrémentée, c'est pour cette raison que je ne comprenais pas hier où vous vouliez m'amener ?
Est-ce que je peux mieux faire ou c'est bon ?
Ensuite je vais essayer de créer une fonction qui retournera le nombre de chiffre après la virgule et si vous le voulez bien, je vous la soumettrai.
MonTableau ne sert à rien, vous utilisez le buffer global. ce buffer pourrait être local à la fonction
vous pourriez durcir un peu la fonction, vous assurer qu'il y a bien un point par exemple dans le buffer (fonction strchr()) (il devrait toujours être là mais à vérifier car je pense que même pour un nombre entier comme 0.0 dtostrf() donnera "0.0000000" et pas juste "0")
Décidément vous inspirez le respect. j'admire vos compétences tant au niveau technique que de la programmation.
Cette fonction fonctionne parfaitement. Je la comprends mais j'ai quelques questions :
Il y a une différence dans la boucle for entre --f et f-- ?
je constate que dans une boucle for, on peut ne pas mettre les instructions à exécuter entre : {}, peut-être parce que l'on termine par : else break; ?
char *recherchePoint = strchr(dtostrf(ChiffreDec, 0, 7, tmpBuffer), '.'); if (recherchePoint == nullptr) return 0; ici *recherchePoint recherche un pointeur, une adresse en mémoire qui contient un point ? du coup si il n'y a pas de pointeur, d'adresse : la valeur du pointeur est nulle d'où le mot clé nullptr ?