Question

Je suivais des tutoriels pour débutants pour OpenGL en C ++, mais comme je l'ai commencé comme programmeur c # il m'a fait prendre beaucoup de choses pour acquis. Donc, mon problème est survenu lorsque je déboguer l'impression mon FPS lecture à la sortie. Je pense que la méthode était quelque chose comme DebugPrintString du haut de ma tête qui a pris un char * et je suis essentiellement d'impression « FPS: x ». J'utilisais scanf_s pour placer la valeur fps dans le tableau de caractères, mais c'est là mon problème. Quelle taille le tableau de caractères doivent être?

Permettez-moi d'élaborer un peu plus: ma lecture de FPS est stockée sous la forme d'un flotteur comme les images / secondes se termine généralement par être pas un nombre agréable. Donc, mon numéro pourrait être 60, ou il pourrait être 59,12345. 60 aurait seulement besoin de 2 octets et 59,12345 aurait besoin 8 (1 pour la période). Donc, je pensais « Oh ok je dois compter le nombre de chiffres qu'il a, pas de problème! » Le garçon était I dans un état de choc.

J'ai fait une méthode pour compter les chiffres, en comptant le côté gauche de la virgule était facile, tout d'abord jeté comme un int pour supprimer les points décimaux et diviser par 10 (en fait, je pense que j'ai eu quelques opérateurs de bits là-bas) et compter le nombre de fois que je peux le faire jusqu'à atteindre 0. et maintenant compter les chiffres sur le côté droit, eh bien je vais juste multiplier par 10, il faut soustraire le chiffre, et faire cela jusqu'à ce qu'il atteigne zéro. La méthode retournerait habituellement 32 je crois. Donc, je WTF'd et avait un coup d'oeil dans le débogage, se retourne quand vous multipliez le flotteur se déplaçant efficacement les colonnes de chiffres à cause de la question de précision bien connu juste ajouté un autre chiffre!

Je l'ai fait googling majeur, mais ne pouvait pas vraiment trouver quoi que ce soit au-dessus de l'omble str [128] et scanf si ensuite faire strlen (str) moins 1 (terminaison null). Mais j'espérais une solution plus élégante. En fin de compte i juste Casted comme int et assez autorisé pour 9999 fps, a également ajouté un contrôle pour voir si le fps> 9999 mais je ne pense pas que des thats jamais qui va se passer. Mieux vaut prévenir que SEG DÉFAUT: (

TLDR: Y at-il un moyen d'obtenir la quantité de chiffres dans un flotteur? Comment scanf fait-il?

Désolé longtemps après, je voulais juste partager ma frustation>: D

Edit: fautes d'orthographe

Était-ce utile?

La solution

Considérant qu'il est C ++ dont nous parlons, pourquoi ne pas aller dans le sens du TSL?

Précision 5 places après la virgule décimale, peut être quantité variable de caractères:

std::stringstream ss;
ss << std::setprecision (5) << std::fixed << f; 
std::string fps = ss.str();

maximales de précision 5 chiffres significatifs:

std::stringstream ss;
ss << std::setprecision (5) << f; 
std::string fps = ss.str();

Autres conseils

Vous pouvez tronquer / forcer le nombre à virgule flottante à ce que la précision souhaitée à l'aide sprintf. Ensuite, le problème disparaît.

Étant donné que les nombres à virgule flottante ne sont pas stockés de façon précise, il n'y a pas vraiment moyen efficace de compter le nombre de chiffres. Ce que vous voulez sans doute faire est de contrôler la longueur du numéro du flotteur fournit et utiliser un tampon avec une taille fixe.

printf(), scanf() et les fonctions connexes, la taille d'un nombre à virgule flottante peuvent être spécifiées en modifiant le spécificateur de type de format. Bien que simple %f peut être le plus commun, il peut être utilisé de façon plus souple en ajoutant des modificateurs entre le % et le f, tels que:

%[width][.precision]f

[width] fait référence à la minimum nombre de chiffres à afficher le nombre (il n'y aura pas troncature si elle passe au-dessus), et [.precision] indique le nombre exact de chiffres à afficher après la virgule .

A titre d'exemple, vous pouvez examiner la sortie du programme suivant:

#include <cstdio>

using std::printf;
int main() {
  float f(59.12345);

  printf("[%f]\n", f);    // [59.123451]
  printf("[%15f]\n", f);  // [      59.123451]
  printf("[%1f]\n", f);   // [59.123451]
  printf("[%.2f]\n", f);  // [59.12]
  printf("[%6.2f]\n", f); // [ 59.12]
  printf("[%4.1f]\n", f); // [59.1]
}

La taille exacte du tableau de caractères serait encore être variable en fonction de la valeur avant la décimale. Mais tant que vous pouvez contrôler la largeur et la précision, l'allocation de mémoire suffisante dans un tableau de caractères (ou le montage du numéro dans un tableau de longueur fixe) devrait être sensiblement plus simple.

Bien John à CashCommons a donné la réponse traditionnelle, il suffit d'utiliser des qualificatifs de format printf pour forcer une certaine largeur. Je trouve généralement que 2 décimales est beaucoup pour les tarifs de cadre. Il vous permet de distinguer entre 30 fps et 29.97 fps, les deux valeurs les plus courantes.

 sprintf (buffer, "%.2f", fps);

Mais si vous voulez savoir ce que le pire des cas serait, theres un moyen de savoir aussi. Commander http://en.wikipedia.org/wiki/IEEE_754-2008 .

Il montre que les valeurs à virgule flottante (32 flotteurs de bits) ont 24 chiffres binaires dans la mantisse, qui correspond à 7.225 chiffres décimaux, appelez 8. Ajouter 5 chiffres pour l'exposant, 1 pour le signe, 1 pour un chef de file 0, 1 pour le point décimal et vous obtenez

 1 + 1 + 8 + 5 = 15 characters

ajouter la place pour un nul final et vous obtenez 16 chiffres.

Il est images par seconde. Il suffit d'utiliser trois chiffres à gauche et un à droite, qui se soucie de ce la représentation à virgule flottante arrive à penser existe en dessous du dixième près?

EDIT en réponse au premier commentaire.

http://en.wikipedia.org/wiki/Floating_point

Si nous sommes vraiment après le nombre de chiffres dans le flotteur, nous devons savoir comment flotte travail. La valeur exacte représentée dans le type float standard IEEE a une certaine quantité de bits habituellement 32 ou 64, qui sont attribués de manière standardisée pour vous donner un montant fixe de chiffres significatifs, et certains exposant de puissance à elle échelle vers le haut ou vers le bas. 24 bits de chiffres significatifs sort à environ sept places décimales. Il y aura toujours une certaine forme de troncature ou erreur d'arrondi à la fin du cours (comme la façon dont un tiers, écrit en décimal, toujours arrondit lorsque vous arrêtez d'écrire les groupes de trois répéter).

Peut-être que votre numéro arrête après sept ou huit chiffres, mais l'erreur d'arrondi machine garde ça va par accident? Il ne fait pas que donner un sens à lire ce genre de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top