Ich versuche gerade einen float in einen string umzuwandeln. Zum Experimentieren und mein Problem besser darzustellen, habe ich folgendes gemacht:
Code: 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;
}
}
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?