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?

Antworten auf die Frage(7)

Ihre Antwort auf die Frage