Algorytm konwersji liczby zmiennoprzecinkowej na tekst

Szukam algorytmu pozwalającego skutecznie zamieniać liczbę zmiennoprzecinkową typu double na tekst. Liczba w standardzie IEEE 754, gdzie jest:

  • 52 bity mantysy
  • 11 bitów wykładnika
  • 1 bit znaku

Znalazłem algorytm konwersji typu float (23/8/1), z zastosowaniem dwóch int'ów, ale ma ograniczenie górne na wykładnik <31 i dolne >-23. Potrzebuję sprytnego sposobu obejścia ograniczeń. Jeden, który wymyśliłem wymaga implementacji wielkich liczb całkowitych i to jest pewna bariera, gdyż w C taki kod jest średnio przejrzysty.

Próbowałem przeanalizować kod snprintf() z bibliotek GNU, ale poległem - ogrom tam #define i #ifdef.

Pytanie jest poważne. UWAGA! nie interesują mnie odpowiedzi w stylu "użyj sprintf("%f", d); - wszelkie takie odpowiedzi będę oznaczał jako obraźliwe i dawał ujemne punkty. Platforma na której muszę tego użyć ma skopany sprintf() i nie ma snprintf() - brak tego drugiego rodzi wycieki kończące się wysypaniem. UWAGA 2! nie interesują mnie rozwiązania w C++, czy Pythonie - szukam algorytmu.

2 lata, 3 miesiące temu | edytowane przez: Manveru 4224121

  • Nie będzie to najlepsza odpowiedź, ale spróbuj się przyjrzeć implementacji z Java'y http://www.docjar.com/html/api/sun/misc/FloatingDecimal.java.html

    Wartość jako łańcucha pobierana jest w taki sposób new FloatingDecimal(f).toJavaFormatString()

    Analiza powinna być ciut łatwiejsza niż bibliotek GNU, z tego co tak na pierwszy rzut oka widać, całą ciężką robotę odwala metoda dtoa( int binExp, long fractBits, int nSignificantBits ) zaczynająca się w linii 524. Dużo tam komentarzy więc może do czegoś się przyda.

  • Pytanie do czego potrzebujesz takiego algorytmu. Jeśli chcesz zapisać wynik w formie czytelnej dla przeciętnego człowieka, to obawiam się że nie zrobisz tego dokładnie - sam podałeś link do Wikipedii, tam jest informacja o przypadkach szczególnych, czyli liczbach zdenormalizowanych, NaN itd; musiałbyś je wszystkie obsłużyć. Jeśli to nie ma być czytelne dla człowieka, a po prostu w formie tekstowej to poważnie zastanowiłbym się nad zapisaniem tego w formie szestnastkowej, przez rzutowanie całego double na kilka intów.

  • A jakby w miejsce liczb 32 bitowych użyć 64 bitowych? Nie zniknie ograniczenie z tamtego algorytmu?

  • Jeśli program będzie w C++ to możesz spróbować wykorzystać klasę ostringstream (zdefiniowaną w pliku nagłówkowym sstream):

    float f;
    ostringstream stream;
    string s;
    
    scanf("%f", f);
    stream << f;
    s = stream.str();
    puts(s);
    

Zaloguj się, aby dodać swoją odpowiedź