Domanda

Come posso creare una stringa in modo da formattare i numeri in virgola mobile in modo che non abbiano virgola decimale o cifre finali quando è un numero intero, ma NON passare alla notazione scientifica per numeri più grandi?

Quando lo faccio:

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);

Ottengo qualcosa del tipo:

my float is 15.6
my int is 5
my large is 7e+07f

Voglio tutta una stringa di singolo formato che dia 15.6, 5 e 700000.

I commenti di causa modificati non eseguono la formattazione:

questo è quello che ho pensato. ma un wrapper è piuttosto scomodo, dato che le stringhe di formato sono incorporate in stringhe di formato più lunghe:

sprintf(buf, "%d %g", myInt, myFloat);

come lo avvolgi?

sprintf(buf, "%d %g", myInt, Wrapper(myFloat));??

cosa dovrebbe restituire Wrapper? O peggio:

sprintf(buf, "%d %s", myInt, Wrapper(myFloat));?? 
È stato utile?

Soluzione

Non credo che tu possa ottenerlo con % g , poiché % g ti dà il più breve di % e o % f .

Quindi, non penso che ci sia un singolo argomento printf che ti soddisfi. Per 15.6, è possibile utilizzare % 2.1f ; per 7000000, è possibile utilizzare % 7.0f .

La tua scommessa migliore è probabilmente quella di scrivere una funzione wrapper che guardi alla dimensione del tuo valore e applichi l'argomento printf corretto.

Altri suggerimenti

Puoi formattare con "%. * f " ;, che ti consente di passare la precisione come parametro separato ad es. sprintf. L'ho usato in passato quando volevo visualizzare bene 0, 1, 2 o forse 3 cifre senza ulteriori 0 finali. Scrivi una piccola funzione di supporto che prende il double / float e restituisce una precisione intera (moltiplicando per 1000 e quindi facendo il modulo 10, 100, 1000). Quindi chiama sprintf con "%. * F " ;, chiama la funzione helper e passa il float.

L'approccio di Mike è ragionevole, ma è possibile calcolare il numero di cifre direttamente utilizzando la funzione log10 e utilizzare floor o ceil per verificare che si abbia effettivamente un valore intero. Qualcosa del tipo:

#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);
}

Disimballando quella catena di chiamate di funzione, prendiamo prima il valore assoluto per assicurarci che l'argomento non sia negativo, aggiungiamo 0,5 al valore intero noto per occuparci di eventuali errori di arrotondamento nel log di calcolo10 di una potenza esatta di 10 , combina log10 e floor per ottenere l'esponente della potenza maggiore di 10 in meno di fabs (x) +0.5 e infine aggiungi 1 per ottenere il numero di cifre necessarie per rappresentare x. Ecco alcuni valori di esempio (da OpenOffice, ma la funzione C log10 dovrebbe calcolare con precisione simile):

         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

Sostituisci% g con% .10g per mostrare fino a 10 cifre significative

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top