2010-03-09 3 views
5

J'ai besoin d'imprimer nombres à virgule flottante avec les exigences de mise en forme suivantes:Obtenir printf() pour laisser tomber la fuite » .0" des valeurs

  • 5.12345 devrait afficher uniquement 5.1

  • 5.0 ne devrait 5 (sans .0)

  • 5.0176 devrait afficher uniquement 5 (sans .01)

Je pensais que printf() pourrait faire quelque chose comme ça ... mais semblent maintenant je ne peux pas le faire fonctionner.

+0

Je pense que nous aurons besoin d'une description plus systématique des résultats que vous voulez. En ce moment, vous avez donné quelques exemples, mais je ne suis pas du tout sûr de ce que vous voudriez pour (disons) une valeur de 15,2. Voulez-vous un maximum de 2 chiffres significatifs, ou afficher uniquement à l'endroit des unités, ou quoi exactement? –

+0

Que voulez-vous dans le cas de '5.06'? Printf est susceptible de l'arrondir à '5.1'. Voulez-vous supprimer le '.1'? –

+0

double possible de [Évitez en zéros à la fin printf()] (http://stackoverflow.com/questions/277772/avoid-trailing-zeroes-in-printf) –

Répondre

1

Pas comme vous l'avez décrit, non. Si vous voulez des décimales conditionnelles, vous devez le faire vous-même.

il a été un moment depuis que je suis déconné avec les formats printf, mais cela semble fonctionner dans la plupart des cas

char *BuildConditionalFormat(double val) 
{ 
    int tenths = (int)(val * 10) % 10; 
    if (tenths == 0) 
     return ".0f"; 
    return ".1f"; 
} 

/* test rig */ 
float f = 5.0; 
printf(BuildConditionalFormat(f), f); /* -> 5 */ 
f = 5.13; 
printf("\n"); 
printf(BuildConditionalFormat(f), f); /* -> 5.1 */ 
printf("\n"); 

Ce respecte vos règles, mais aussi donner une leçon intéressante dans laquelle virgule flottante pue parce que 5.1 -> 5. Pourquoi? Parce que 5.1 ne représente pas proprement (sur ma machine) comme un flotteur - c'est 5.09999 et un peu plus de changement.

Il y a des chances que vous devez en apprendre davantage sur plancher() et ceil() aussi ...

1

printf() peuvent utiliser des chaînes de formatage. Regardez les options de largeur et de précision des chaînes de formatage:

printf("%.1f", 5.12345f); 

Ce imprimera 5.1.

Malheureusement, il n'a pas la possibilité de déterminer automatiquement, sans guide, ce qu'il faut afficher. (Par exemple, votre dernière option n'est pas claire pour moi - pourquoi devrait-elle laisser tomber le ".0176", sans que vous lui disiez que vous ne voulez pas de points décimaux?)

+0

Cela ne baissera pas de dire hors .0 FYI 5.0. –

+1

mais il imprimera 5.0 au cas où 5.0. OP veut imprimer 5 dans ce cas. –

+0

@Dana: Je ne suis pas sûr que ce soit vrai. Regardez la première option de l'OP - ils veulent 5.1 pour 5.12345 - aucun 0 impliqué là ... –

0

Vous pouvez dire à printf d'imprimer le nombre de chiffres spécifié après ' . ' , mais si vous voulez différer le format en fonction de la valeur, vous devez écrire du code pour distinguer les cas intéressants pour vous.

1

Aucun des opérateurs de formatage ne le supporte, mais vous pouvez d'abord filtrer le float en sprintf(), puis tronquer la chaîne le cas échéant. Cela vous évite d'avoir à convertir le flotteur en chaîne et la logique de faire le reste est facile.

+0

Un problème avec ceci est qu'il ne prend pas facilement en charge l'arrondi, si cela est souhaitable. Dans l'article original, aucun des exemples ne montre quelque chose qui aurait besoin d'être arrondi, donc nous ne savons pas si c'est une exigence ou non. – Jon

8

Vous pouvez obtenir sorte de près les résultats que vous voulez en utilisant "% g"

#include <stdio.h> 

int main(int argc, char* argv[]) 
{ 
     printf("%.6g\n", 5.12345f); 
     printf("%.6g\n", 5.0f); 
     printf("%.6g\n", 5.0176f); 
     return 0; 
} 

sortie:

5.12345 
5 
5.0176 

"% g" supprimera zéros.

+6

'% .2g' passerait les trois tests de l'OP. –

+3

@ Max, j'ai regardé dans la page de manuel. S'il dit '% .2g' et imprime' 100', il obtient '1.00e + 02' (si l'exposant est supérieur ou égal à la précision, le style scientifique est utilisé par'% g'). Je pense que ce n'est peut-être pas ce qu'il veut. –

2

Semble que vous voulez imprimer 1 décimale, et si cet endroit est 0, déposez-le.Cette fonction devrait fonctionner correctement:

// prints the float into dst, returns the number 
// of chars in the manner of snprintf. A truncated 
// output due to size limit is not altered. 
// A \0 is always appended. 
int printit(float f, char *dst, int max) { 
    int c = snprintf(dst, max, "%.1f", f); 

    if(c > max) { 
    return c; 
    } 

    // position prior to '\0' 
    c--; 

    while(dst[c] == '0') { 
    c--; 
    if(dst[c] == '.') { 
     c--; 
     break; 
    } 
    } 
    dst[c + 1] = '\0'; 
    return c + 1; 
} 

int main(void) { 
    char num1[10], num2[10], num3[10]; 
    printit(5.12345f, num1, 10); 
    printit(5.0f, num2, 10); 
    printit(5.0176f, num3, 10); 
    printf("%s\n%s\n%s\n", num1, num2, num3); 
} 
Questions connexes