diff --git a/BeefLibs/corlib/src/Double.bf b/BeefLibs/corlib/src/Double.bf index 6d93994a..1ea43080 100644 --- a/BeefLibs/corlib/src/Double.bf +++ b/BeefLibs/corlib/src/Double.bf @@ -196,12 +196,12 @@ namespace System [CallingConvention(.Stdcall), CLink] 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) { char8[128] outBuff = ?; - int len = ToString((double)this, &outBuff); + int len = ToString((double)this, &outBuff, false); strBuffer.Append(&outBuff, len); } @@ -212,6 +212,13 @@ namespace System ToString(outString); 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); } } diff --git a/BeefLibs/corlib/src/Float.bf b/BeefLibs/corlib/src/Float.bf index ef901df2..ed50ffb1 100644 --- a/BeefLibs/corlib/src/Float.bf +++ b/BeefLibs/corlib/src/Float.bf @@ -144,13 +144,12 @@ namespace System [CallingConvention(.Stdcall), CLink] 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) { char8[128] outBuff = ?; - //ftoa((float)this, &outBuff); - int len = ToString((float)this, &outBuff); + int len = ToString((float)this, &outBuff, false); strBuffer.Append(&outBuff, len); } @@ -161,6 +160,13 @@ namespace System ToString(outString); 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); } diff --git a/BeefRT/rt/Internal.cpp b/BeefRT/rt/Internal.cpp index 35a37316..4bcc49a4 100644 --- a/BeefRT/rt/Internal.cpp +++ b/BeefRT/rt/Internal.cpp @@ -179,13 +179,13 @@ namespace bf struct Float { private: - BFRT_EXPORT static int ToString(float f, char* outStr); + BFRT_EXPORT static int ToString(float f, char* outStr, bool roundTrip); }; struct Double { 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); - int len = (int)strlen(outStr); - for (int i = 0; outStr[i] != 0; i++) + if (!roundTrip) { - if (outStr[i] == '.') - { - int checkC = len - 1; - while (true) - { - char c = outStr[checkC]; - if (c == '.') - { - return checkC; - } - 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 digits; + if (d > 100000) + digits = 1; + else if (d > 10000) + digits = 2; + else if (d > 1000) + digits = 3; + else if (d > 100) + digits = 4; + else if (d > 10) + digits = 5; + else + digits = 6; + + sprintf(outStr, "%1.*f", digits, d); + } + else + sprintf(outStr, "%1.9g", d); -static int ToString(double d, char* outStr) -{ - sprintf(outStr, "%1.17g", d); int len = (int)strlen(outStr); for (int i = 0; outStr[i] != 0; i++) { @@ -1026,22 +1001,99 @@ static int ToString(double d, char* outStr) 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 auto result = std::to_chars(outStr, outStr + 256, f); return (int)(result.ptr - outStr); #else - return ::ToString(f, outStr); + return ::ToString(f, outStr, roundTrip); #endif } -int Double::ToString(double d, char* outStr) +int Double::ToString(double d, char* outStr, bool roundTrip) { #ifdef USE_CHARCONV auto result = std::to_chars(outStr, outStr + 256, d); return (int)(result.ptr - outStr); #else - return ::ToString(d, outStr); + return ::ToString(d, outStr, roundTrip); #endif }