1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Improved default float printing, added 'R' roundtrip format

This commit is contained in:
Brian Fiete 2022-05-24 11:17:23 -07:00
parent 1aa42cba8b
commit 470ce96bb9
3 changed files with 121 additions and 56 deletions

View file

@ -196,12 +196,12 @@ namespace System
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink]
static extern int32 ftoa(float val, char8* str); static extern int32 ftoa(float val, char8* str);
static extern int32 ToString(double val, char8* str); static extern int32 ToString(double val, char8* str, bool roundTrip);
public override void ToString(String strBuffer) public override void ToString(String strBuffer)
{ {
char8[128] outBuff = ?; char8[128] outBuff = ?;
int len = ToString((double)this, &outBuff); int len = ToString((double)this, &outBuff, false);
strBuffer.Append(&outBuff, len); strBuffer.Append(&outBuff, len);
} }
@ -212,6 +212,13 @@ namespace System
ToString(outString); ToString(outString);
return; return;
} }
else if (format == "R")
{
char8[128] outBuff = ?;
int len = ToString((double)this, &outBuff, true);
outString.Append(&outBuff, len);
return;
}
NumberFormatter.NumberToString(format, (double)this, formatProvider, outString); NumberFormatter.NumberToString(format, (double)this, formatProvider, outString);
} }
} }

View file

@ -144,13 +144,12 @@ namespace System
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink]
static extern int32 ftoa(float val, char8* str); static extern int32 ftoa(float val, char8* str);
static extern int32 ToString(float val, char8* str); static extern int32 ToString(float val, char8* str, bool roundTrip);
public override void ToString(String strBuffer) public override void ToString(String strBuffer)
{ {
char8[128] outBuff = ?; char8[128] outBuff = ?;
//ftoa((float)this, &outBuff); int len = ToString((float)this, &outBuff, false);
int len = ToString((float)this, &outBuff);
strBuffer.Append(&outBuff, len); strBuffer.Append(&outBuff, len);
} }
@ -161,6 +160,13 @@ namespace System
ToString(outString); ToString(outString);
return; return;
} }
else if (format == "R")
{
char8[128] outBuff = ?;
int len = ToString((float)this, &outBuff, true);
outString.Append(&outBuff, len);
return;
}
NumberFormatter.NumberToString(format, (float)this, formatProvider, outString); NumberFormatter.NumberToString(format, (float)this, formatProvider, outString);
} }

View file

@ -179,13 +179,13 @@ namespace bf
struct Float struct Float
{ {
private: private:
BFRT_EXPORT static int ToString(float f, char* outStr); BFRT_EXPORT static int ToString(float f, char* outStr, bool roundTrip);
}; };
struct Double struct Double
{ {
private: private:
BFRT_EXPORT static int ToString(double f, char* outStr); BFRT_EXPORT static int ToString(double f, char* outStr, bool roundTrip);
}; };
} }
} }
@ -932,54 +932,29 @@ void bf::System::FFI::FFILIB::Call(bf::System::FFI::FFILIB::FFICIF* cif, void* f
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static int ToString(float d, char* outStr) static int ToString(float d, char* outStr, bool roundTrip)
{ {
sprintf(outStr, "%1.9g", d); if (!roundTrip)
int len = (int)strlen(outStr);
for (int i = 0; outStr[i] != 0; i++)
{ {
if (outStr[i] == '.') int digits;
{ if (d > 100000)
int checkC = len - 1; digits = 1;
while (true) else if (d > 10000)
{ digits = 2;
char c = outStr[checkC]; else if (d > 1000)
if (c == '.') digits = 3;
{ else if (d > 100)
return checkC; digits = 4;
} else if (d > 10)
else if (c != '0') digits = 5;
{ else
for (int j = i + 1; j <= checkC; j++) digits = 6;
if (outStr[j] == 'e')
return len; sprintf(outStr, "%1.*f", digits, d);
return checkC + 1; }
} else
checkC--; sprintf(outStr, "%1.9g", d);
}
}
}
if ((len == 3) && (outStr[0] == 'i'))
{
strcpy(outStr, "Infinity");
return 8;
}
if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
{
strcpy(outStr, "-Infinity");
return 9;
}
if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
{
strcpy(outStr, "NaN");
return 3;
}
return len;
}
static int ToString(double d, char* outStr)
{
sprintf(outStr, "%1.17g", d);
int len = (int)strlen(outStr); int len = (int)strlen(outStr);
for (int i = 0; outStr[i] != 0; i++) for (int i = 0; outStr[i] != 0; i++)
{ {
@ -1026,22 +1001,99 @@ static int ToString(double d, char* outStr)
return len; return len;
} }
int Float::ToString(float f, char* outStr) static int ToString(double d, char* outStr, bool roundTrip)
{
if (!roundTrip)
{
int digits;
if (d > 1000000000)
digits = 1;
else if (d > 100000000)
digits = 2;
else if (d > 10000000)
digits = 3;
else if (d > 1000000)
digits = 4;
else if (d > 100000)
digits = 5;
else if (d > 10000)
digits = 6;
else if (d > 1000)
digits = 7;
else if (d > 100)
digits = 8;
else if (d > 10)
digits = 9;
else
digits = 10;
sprintf(outStr, "%1.*f", digits, d);
}
else
sprintf(outStr, "%1.17g", d);
int len = (int)strlen(outStr);
for (int i = 0; outStr[i] != 0; i++)
{
if (outStr[i] == '.')
{
int checkC = len - 1;
while (true)
{
char c = outStr[checkC];
if (c == '.')
{
return checkC;
}
else if (c == 'e')
{
return len;
}
else if (c != '0')
{
for (int j = i + 1; j <= checkC; j++)
if (outStr[j] == 'e')
return len;
return checkC + 1;
}
checkC--;
}
}
}
if ((len == 3) && (outStr[0] == 'i'))
{
strcpy(outStr, "Infinity");
return 8;
}
if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
{
strcpy(outStr, "-Infinity");
return 9;
}
if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
{
strcpy(outStr, "NaN");
return 3;
}
return len;
}
int Float::ToString(float f, char* outStr, bool roundTrip)
{ {
#ifdef USE_CHARCONV #ifdef USE_CHARCONV
auto result = std::to_chars(outStr, outStr + 256, f); auto result = std::to_chars(outStr, outStr + 256, f);
return (int)(result.ptr - outStr); return (int)(result.ptr - outStr);
#else #else
return ::ToString(f, outStr); return ::ToString(f, outStr, roundTrip);
#endif #endif
} }
int Double::ToString(double d, char* outStr) int Double::ToString(double d, char* outStr, bool roundTrip)
{ {
#ifdef USE_CHARCONV #ifdef USE_CHARCONV
auto result = std::to_chars(outStr, outStr + 256, d); auto result = std::to_chars(outStr, outStr + 256, d);
return (int)(result.ptr - outStr); return (int)(result.ptr - outStr);
#else #else
return ::ToString(d, outStr); return ::ToString(d, outStr, roundTrip);
#endif #endif
} }