2015-05-16 25 views
7

Jako osobisty projekt, napisałem kompilator dla mojego własnego języka w stylu C, aby celować w emulator procesora własnego projektu.Jak języki obsługują drukowanie płaszczyzn pod maską?

W tym celu chcę zaimplementować standardową bibliotekę zmiennoprzecinkową (typowa pojedyncza precyzja IEEE), ale starałem się wymyślić sposób na wydrukowanie elementów pływających w łatwy do odczytania sposób (np. 1.2345 zamiast nieprzetworzonej liczby całkowitej), najlepsze, co mogę myśleć, to generowanie wartości dla logów 2 i wykonywanie pewnych dziwnych multiplikacji w celu uzyskania liczby w odpowiedniej postaci do drukowania.

Czy istnieje algorytm przekształcania elementu pływającego w formularz, który można łatwo wydrukować, lub w celu wydrukowania obiektu typu float, który można zaimplementować bez korzystania z wersji printf("%f",float_value); lub odlewania w języku C?

+1

Pewnie, dlaczego nie spojrzeć na realizację z 'printf'? –

+0

Lub jeden z nich, na przykład 'glibc's, ponieważ jego kod źródłowy jest dostępny do pobrania. –

+0

możliwy duplikat [kodu źródłowego funkcji c/C++] (http://stackoverflow.com/questions/1127328/source-code-of-cc-functions) –

Odpowiedz

3

Może to być brudny hack funkcji, ale możesz użyć tego jako podstawy dla prawidłowego wyświetlania liczb zmiennoprzecinkowych. Nie używa żadnej innej funkcji pomocniczej, poza putchar, aby faktycznie wydrukować coś, i nie obejmuje wszystkich sytuacji (jak twój numer będący NaN, a nawet negatywnym!), Ale, cóż, to tylko punkt wyjścia :

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

można go przetestować tutaj: http://goo.gl/V4pgNZ

+3

Nie, nie można tego użyć jako podstawy do prawidłowej funkcji. To tylko brudny hack i przejście od niego do czegoś, co działa poprawnie, trzeba wyrzucić. W swojej obronie, aby zaimplementować poprawne binarne-dziesiętne w C od zera, trzeba zacząć od wdrożenia przynajmniej podstawowej biblioteki bignum (http://www.openwall.com/lists/musl/2012/04/10/6), ale jeśli ktoś nie chce zrobić poprawnej wersji, można przynajmniej zrobić http://www.opensource.apple.com/source/ruby/ruby-18/ruby/missing/strtod.c?txt. I przeczytaj http://www.exploringbinary.com/ of couse. –

6

Jak rozumiem, obecny stan techniki do drukowania liczb zmiennoprzecinkowych jest rodzina Grisu algorytmów, Florian Loitsch. Możesz przeczytać artykuł here.

Dla nieco łatwiejsze wprowadzenie do zagadnień w konwersję binarną zmiennoprzecinkowe na dziesiętne (i vice versa), gorąco polecam stronę Rick Regan, http://www.exploringbinary.com/