[c++] [selfmade] float zu string konvertieren

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.

[c++] [selfmade] float zu string konvertieren

Beitragvon Goderion » 19.11.2017, 15:26

Hallo.

Ich versuche gerade einen float in einen string umzuwandeln. Zum Experimentieren und mein Problem besser darzustellen, habe ich folgendes gemacht:
Code: Ansicht erweitern :: Alles auswählen
int FloatToStringTest(void)
{
        struct StructFloat32
        {
                unsigned int Mantissa : 23;
                unsigned int Exponent : 8;
                unsigned int Sign : 1;
        };

        union UnionFloat32
        {
                float Value;
                StructFloat32 Struct;
        };

        UnionFloat32 Test;
        Test.Value = 234.435f;

        unsigned int Mantissa = Test.Struct.Mantissa + 0x00800000;
        char Exponent = Test.Struct.Exponent - 127;
        char Sign = Test.Struct.Sign;

        if (128 == Exponent)
        {
                if (0 == Mantissa)
                {
                        if (0 == Sign)
                        {
                                // Infinity
                        }
                        else
                        {
                                // -Infinity
                        }
                }
                else
                {
                        // NaN
                }

                return 0;
        }

        if (Exponent >= 23)
        {
                // Problem 1: Überlauf möglich

                unsigned __int64 Integer = Mantissa;
                Integer <<= (Exponent - 23); // Überlauf möglich

                return 0;
        }
        else if (Exponent >= 0)
        {
                // Sollte immer funktionieren?

                unsigned char Shift = 23 - Exponent;
                unsigned __int64 Integer = Mantissa >> Shift;
                unsigned __int64 Fraction = Mantissa - (Integer << Shift);
                unsigned __int64 Divisor = 1ULL << Shift;
                unsigned __int64 Precision = 1000000000;
                unsigned __int64 Float = (Fraction + Divisor) * Precision / Divisor;
                float Check = Fraction / (float)Divisor;

                return 0;
        }
        else
        {
                // Problem 2: Überlauf möglich

                unsigned char Shift = 23 - Exponent;
                Shift = 63;
                unsigned __int64 Fraction = Mantissa;
                unsigned __int64 Divisor = 1ULL << Shift; // Shift > 63 = Überlauf
                unsigned __int64 Precision = 1000000000;
                unsigned __int64 Float = (Fraction + Divisor) * Precision / Divisor; // Überlauf möglich
                float Check = Fraction / (float)Divisor;

                return 0;
        }
}

Mein Probleme scheinen nur die "Überläufe" zu sein. Gäbe es einen __int128 oder für double einen __int256, hätte ich vermutlich kein Problem.
Wie ich aus einer Ganzzahl/int einen string erzeuge, stellt kein Problem dar. Mein Problem liegt nur bei hohen Exponenten.

Ich habe ein wenig sprintf_s debuggt, und dort scheint man auch, nachdem man erstmal den "Template-Terror" hinter sich hat, eine besonders große Ganzzahl (big_integer) zu nutzen. Vielleicht sollte ich eine Klasse für besonders große Ganzzahlen programmieren und damit meine Probleme lösen?
Goderion
 
Beiträge: 58
Registriert: 16.09.2012, 12:02
Alter Benutzername: Goderion

Re: [c++] [selfmade] float zu string konvertieren

Beitragvon Krishty » 19.11.2017, 15:32

Alle Plattformen und Programmiersprachen nutzen David Gays dtoa.c, zu dem es auch irgendwo ein Paper gibt. AFAIK, ja, nutzt das Big Integer Math. In dem Quelltext gibt es einen Kommentar /* Can we do an exact computation with 64-bit integer arithmetic? */, wahrscheinlich ist alles danach für dich von Interesse.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
 
Beiträge: 6024
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy

Re: [c++] [selfmade] float zu string konvertieren

Beitragvon Goderion » 24.11.2017, 15:07

Vielen Dank für die Info.

dtoa.c von David M. Gay finde ich sehr anstrengend zu Lesen/Verstehen. Unzählige Präprozessor-Anweisungen und Variablen-Namen, wie von einem Mathematiker. ^^

Ich habe mir jetzt selber eine Klasse zum Rechnen mit großen Ganzzahlen programmiert und konvertiere damit Fließkommazahlen (float, double) in einen String. Die eigene Konvertierung ist zwar ziemlich langsam (ca. 10 mal so langsam wie sptrinf), aber da ich die Umwandlung momentan nur für Benutzereingaben benötige, ist das vorerst egal. Eine Optimierung zugunsten der Geschwindigkeit kann ich ja später noch machen. Wichtiger ist für mich, dass ich die Funktion verstehe und sie korrekt arbeitet.

Hier meine (unoptimierte/einfache) Klasse zum Rechnen mit großen (positiven) Ganzzahlen:
TemplateUIntX.h
(8.92 KiB) 26-mal heruntergeladen


Hinweise, Infos, Bug-Funde und Kritik sind immer willkommen.
Goderion
 
Beiträge: 58
Registriert: 16.09.2012, 12:02
Alter Benutzername: Goderion


Zurück zu Algorithmen und Datenstrukturen

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron