Browse Source

Improved default float printing, added 'R' roundtrip format

Brian Fiete 3 years ago
parent
commit
470ce96bb9
3 changed files with 81 additions and 16 deletions
  1. 9 2
      BeefLibs/corlib/src/Double.bf
  2. 9 3
      BeefLibs/corlib/src/Float.bf
  3. 63 11
      BeefRT/rt/Internal.cpp

+ 9 - 2
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);
 		}
     }

+ 9 - 3
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);
 		}
 

+ 63 - 11
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,9 +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 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);
+
 	int len = (int)strlen(outStr);
 	for (int i = 0; outStr[i] != 0; i++)
 	{
@@ -947,7 +967,11 @@ static int ToString(float d, char* outStr)
 				if (c == '.')
 				{
 					return checkC;
-				}				
+				}
+				else if (c == 'e')
+				{
+					return len;
+				}
 				else if (c != '0')
 				{
 					for (int j = i + 1; j <= checkC; j++)
@@ -977,9 +1001,37 @@ static int ToString(float d, char* outStr)
 	return len;
 }
 
-static int ToString(double d, char* outStr)
+static int ToString(double d, char* outStr, bool roundTrip)
 {
-	sprintf(outStr, "%1.17g", d);
+	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++)
 	{
@@ -1026,22 +1078,22 @@ static int ToString(double d, char* outStr)
 	return len;
 }
 
-int Float::ToString(float f, char* outStr)
+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
 }