format de chaîne avec% g en C
Question
Comment créer une chaîne de sorte qu'elle formate les nombres en virgule flottante de manière à ne pas comporter de virgule décimale ou de chiffre en fin de chaîne lorsqu'il s'agit d'un entier, mais à NE PAS passer à la notation scientifique pour les grands nombres?
Quand je le fais:
float myFloat= 15.6f;
float myInt = 5.0f;
float myLarge = 7000000.0f;
sprintf(out, "my float is %g", myFloat);
sprintf(out, "my int is %g", myInt);
sprintf(out, "my large is %g", myLarge);
Je reçois quelque chose comme:
my float is 15.6 my int is 5 my large is 7e+07f
Je veux toute une chaîne de format unique qui donnera 15.6, 5 et 700000.
Les commentaires de cause modifiés ne formatent pas:
c'est ce que je pensais. mais un wrapper est plutôt gênant car les chaînes de format sont incorporées dans des chaînes de format plus longues:
sprintf(buf, "%d %g", myInt, myFloat);
comment enroulez-vous cela?
sprintf(buf, "%d %g", myInt, Wrapper(myFloat));??
Que doit retourner Wrapper? Ou pire:
sprintf(buf, "%d %s", myInt, Wrapper(myFloat));??
La solution
Je ne pense pas que vous puissiez obtenir cela avec % g
, car % g
vous indique le plus court des % e
ou % f
.
Donc, je ne pense pas qu'un seul argument printf
vous satisfasse. Pour 15.6, vous pourriez utiliser % 2.1f
; pour 7000000, vous pouvez utiliser % 7.0f
.
Votre meilleur choix est probablement d'écrire une fonction wrapper qui consisterait en la taille de votre valeur et en appliquant le bon argument printf
.
Autres conseils
Vous pouvez formater avec "%. * f", ce qui vous permet de transmettre la précision en tant que paramètre distinct à, par exemple. sprintf. Je l'ai déjà utilisé lorsque je voulais afficher 0, 1, 2 ou peut-être 3 chiffres sans jolies 0. Ecrivez une petite fonction d'assistance qui prend le double / float et renvoie une précision entière (en multipliant par 1000 puis en effectuant modulo 10, 100, 1000). Appelez ensuite sprintf avec "%. * F", appelez la fonction d'assistance et transmettez le flottant.
L’approche de Mike est raisonnable, mais vous pouvez calculer le nombre de chiffres directement à l’aide de la fonction log10 et utiliser floor ou ceil pour vérifier que vous avez bien une valeur entière. Quelque chose comme:
#include <math.h>
double x;
...
if (floor(x) == x && x != 0.0) { // x is an non-zero integer value
int digits = floor(log10(fabs(x)+0.5)) + 1;
printf("x is %.*f\n", digits, x);
}
En décompressant cette chaîne d’appels de fonction, nous prenons d’abord la valeur absolue pour nous assurer que l’argument est non négatif, ajoutez 0,5 à la valeur entière connue pour prendre en charge les éventuelles erreurs d’arrondi dans le calcul du log10 d’une puissance exacte de 10 , combinez log10 et floor pour obtenir l’exposant de la plus grande puissance de 10 de moins que les fabs (x) +0,5 et, enfin, ajoutez 1 pour obtenir le nombre de chiffres nécessaires pour représenter x. Voici quelques exemples de valeurs (à partir d'OpenOffice, mais la fonction C log10 doit calculer avec une précision similaire):
x log10(x+0.5)
1 0.176091259055681000
9 0.977723605288848000
10 1.021189299069940000
99 1.997823080745730000
100 2.002166061756510000
999 2.999782798454140000
1000 3.000217092972230000
10000 4.000021714181250000
100000 5.000002171466980000
1000000 6.000000217147190000
10000000 7.000000021714720000
100000000 8.000000002171470000
1000000000 9.000000000217150000
Remplacez% g par% .10g pour afficher jusqu'à 10 chiffres significatifs