drukowanie integralnej części liczby zmiennoprzecinkowej
Próbuję dowiedzieć się, jak drukować liczby zmiennoprzecinkowe bez korzystania z funkcji biblioteki. Wydrukowanie części dziesiętnej liczby zmiennoprzecinkowej okazało się dość łatwe. Drukowanie integralnej części jest trudniejsze:
static const int base = 2;
static const char hex[] = "0123456789abcdef";
void print_integral_part(float value)
{
assert(value >= 0);
char a[129]; // worst case is 128 digits for base 2 plus NUL
char * p = a + 128;
*p = 0;
do
{
int digit = fmod(value, base);
value /= base;
assert(p > a);
*--p = hex[digit];
} while (value >= 1);
printf("%s", p);
}
Drukowanie integralnej częściFLT_MAX
działa bez zarzutu z podstawą 2 i podstawą 16:
11111111111111111111111100000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000 (base 2)
ffffff00000000000000000000000000 (base 16)
Jednak drukowanie w bazie 10 powoduje błędy po pierwszych 7 cyfrach:
340282368002860660002286082464244022240 (my own function)
340282346638528859811704183484516925440 (printf)
Zakładam, że jest to wynik podziału przez 10. Jest lepiej, jeśli użyję podwójnego zamiast pływaka:
340282346638528986604286022844204804240 (my own function)
340282346638528859811704183484516925440 (printf)
(Jeśli nie wierzyszprintf
, wchodzić2^128-2^104
w Wolfram Alpha. Jest prawidłowa.)
A teraz jakprintf
uda ci się wydrukować poprawny wynik? Czy korzysta z niektórych urządzeń typu bigint wewnętrznie? A może brakuje mi sztuczki zmiennoprzecinkowej?