Drucken des integralen Teils einer Gleitkommazahl
Ich versuche herauszufinden, wie man Gleitkommazahlen druckt, ohne Bibliotheksfunktionen zu verwenden. Das Drucken des Dezimalteils einer Gleitkommazahl erwies sich als recht einfach. Das Drucken des integralen Teils ist schwieriger:
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);
}
Drucken des integralen Teils vonFLT_MAX
funktioniert einwandfrei mit base 2 und base 16:
11111111111111111111111100000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000 (base 2)
ffffff00000000000000000000000000 (base 16)
Das Drucken in Basis 10 führt jedoch zu Fehlern nach den ersten 7 Ziffern:
340282368002860660002286082464244022240 (my own function)
340282346638528859811704183484516925440 (printf)
Ich gehe davon aus, dass dies ein Ergebnis der Division durch 10 ist. Es wird besser, wenn ich double anstelle von float verwende:
340282346638528986604286022844204804240 (my own function)
340282346638528859811704183484516925440 (printf)
(Wenn du nicht glaubstprintf
, eingeben2^128-2^104
in Wolfram Alpha. Das ist richtig.)
Nun, wie geht das?printf
das richtige ergebnis drucken? Verwendet es intern einige Bigint-Einrichtungen? Oder gibt es einen Fließkomma-Trick, den ich vermisse?