2015-05-16 8 views
7

Come progetto personale, ho scritto un compilatore per il mio linguaggio C come target per un emulatore di CPU del mio progetto.In che modo le lingue gestiscono la stampa fluttua sotto il cofano?

Come parte di questo, voglio implementare una libreria a virgola mobile standard (tipica IEEE singola precisione), ma ho faticato a pensare a un modo di stampare i float in un modo facile da leggere (come in 1.2345 anziché il numero intero di dati non elaborati), il meglio che potrei pensare è generare valori per il registro 2 e fare alcune moltiplicazioni dispari per ottenere il numero in un formato adatto per la stampa.

Esiste un algoritmo per convertire un float in una forma facilmente stampabile o per stampare un float che può essere implementato senza utilizzare printf("%f",float_value); o digitare i cast in un linguaggio simile a C?

+1

Certo, perché non dare un'occhiata a un'implementazione di 'printf'? –

+0

Oppure uno di questi, ad esempio 'glibc', poiché il codice sorgente è disponibile per il download. –

+0

possibile duplicato di [codice sorgente delle funzioni c/C++] (http://stackoverflow.com/questions/1127328/source-code-of-cc-functions) –

risposta

3

Potrebbe trattarsi di un errore di una funzione, ma è possibile utilizzarlo come base per una funzione per visualizzare correttamente i numeri in virgola mobile. Non usa nessuna altra funzione ausiliaria, a parte putchar per stampare qualcosa in realtà, e non copre tutte le situazioni (come il tuo numero è un NaN, o addirittura un negativo!) Ma, beh, è ​​solo un punto di partenza :

#include <stdio.h> 

void printfloat (float n) 
{ 
    int whole = n; 
    int power = 1; 
    int digit; 

    /* Find out the largest divisor for printing the integer part */ 
    while (whole>=1) 
    { 
     whole /= 10; 
     power *= 10; 
    } 
    power /= 10; 

    /* Prints the integer part of the number */ 
    whole = n; 
    while (power>=1) 
    { 
     digit = whole/power; 
     whole %= power; 
     putchar ('0'+digit); 
     power /= 10; 
    } 

    /* Prints the decimal point */ 
    putchar ('.'); 

    /* And now the fractional part */ 
    n = n-(int)n; 
    while(n!=0) 
    { 
     digit = n*10; 
     putchar ('0'+digit); 
     n*=10; 
     n = n-(int)n; 
    } 
    putchar ('\n'); 
} 

int main() 
{ 
    float n = 123.45678; 

    printfloat(n); 
    return 0; 
} 

è possibile verificare qui: http://goo.gl/V4pgNZ

+3

No, questo non può essere usato come base per una funzione corretta. È solo un trucco sporco, e per passare da qualcosa a qualcosa che funziona correttamente è necessario buttarlo via. A sua difesa, per implementare un corretto binario-decimale in C da zero, è necessario iniziare con l'implementazione di una libreria bignum almeno rudimentale (http://www.openwall.com/lists/musl/2012/04/10/6) ma se non si vuole fare la versione corretta, si può almeno fare http://www.opensource.apple.com/source/ruby/ruby-18/ruby/missing/strtod.c?txt. E leggere http://www.exploringbinary.com/ di couse. –

6

quanto ho capito, lo stato attuale della tecnica per la stampa di numeri in virgola mobile è la famiglia di algoritmi Grisu, da Florian Loitsch. È possibile leggere il documento here.

Per un'introduzione po 'più facile per i problemi nella conversione in virgola mobile binario a decimale (e viceversa), raccomando sito di Rick Regan, http://www.exploringbinary.com/

Problemi correlati