2010-02-15 11 views

risposta

7

L'approccio scelto dipenderà dal possibile intervallo di valori. Sicuramente hai una conoscenza interna della gamma possibile e potresti essere interessato solo a conversioni in un intervallo più ristretto.

Quindi, supponiamo di essere interessato solo al valore intero. In questo caso, assegnerei il numero a int o long, a questo punto il problema diventa abbastanza ovvio.

Oppure, supponiamo che l'intervallo non includa esponenti di grandi dimensioni, ma sei interessato a più cifre di frazione. Per ottenere tre cifre di frazione, potrei dire int x = f * 1000;, convertire x e quindi inserire il punto decimale come operazione stringa.

In caso contrario, un float o double ha un bit di segno, una frazione e un esponente. C'è un 1 nascosto nella frazione. (I numeri sono normalizzati fino a quando non hanno zero iniziali, a quel punto eseguono un ulteriore spostamento per ottenere un ulteriore bit di precisione.) Il numero è quindi uguale alla frazione (più un '1' iniziale) * 2 ** esponente . Con praticamente tutti i sistemi che utilizzano la rappresentazione IEEE 754, è sufficiente utilizzare this Wikipedia IEEE 754 page per comprendere il formato. Non è quello diverso dalla semplice conversione di un numero intero.

Per singola precisione, una volta a ottenere l'esponente e la frazione, il valore Nota 1 del numero è poi (frac/2 + 1) * 2 exp, o frac * 2 exp - 23 + 2 exp.

Ecco un esempio che dovrebbe iniziare in una conversione utile:

$ cat t.c 
#include <stdio.h> 

void xconvert(unsigned frac) 
{ 
    if (frac) { 
    xconvert(frac/10); 
    printf("%c", frac % 10 | '0'); 
    } 
} 

void convert(unsigned i) 
{ 
    unsigned sign, exp, frac; 

    sign = i >> 31; 
    exp = (i >> (31 - 8)) - 127; 
    frac = i & 0x007fffff; 
    if (sign) 
    printf("-"); 
    xconvert(frac); 
    printf(" * 2 ** %d + 2 ** %d\n", exp - 23, exp); 
    printf("\n"); 
} 

int main(void) 
{ 
    union { 
    float f; 
    unsigned i; 
    } u; 

    u.f = 1.234e9; 
    convert(u.i); 
    return 0; 
} 
$ ./a.out 
1252017 * 2 ** 7 + 2 ** 30 

Nota 1. In questo caso la frazione viene convertito come se il punto binario era a destra, invece di sinistra, con regolazioni compensative fatte all'esponente e al bit nascosto.

0

Anche in un sistema embedded, si fatica a battere le prestazioni di ftoa. Perché reinventare la ruota?

+3

'ftoa' potrebbe non essere effettivamente disponibile nelle librerie fornite. Dopo tutto, non fa parte della libreria standard e, anche se lo fosse, non è raro che i sistemi incorporati utilizzino implementazioni indipendenti che omettono gran parte della libreria standard. – jamesdlin

0
#include<stdio.h> 
void flot(char* p, float x) 
{ 
    int n,i=0,k=0; 
    n=(int)x; 
    while(n>0) 
    { 
    x/=10; 
    n=(int)x; 
    i++; 
} 
*(p+i) = '.'; 
x *= 10; 
n = (int)x; 
x = x-n; 
while(n>0) 
{ 
    if(k == i) 
     k++; 
    *(p+k)=48+n; 
    x *= 10; 
    n = (int)x; 
    x = x-n; 
    k++; 
} 
*(p+k) = ''; 
} 

int main() 
{ 
    float x; 
    char a[20]={}; 
    char* p=&a; 
    printf("Enter the float value."); 
    scanf("%f",&x); 
    flot(p,x); 
    printf("The value=%s",p); 
    getchar(); 
    return 0; 
} 
Problemi correlati