Browse Source

Implemented parsing of scientific notation in string_toDouble, because it is sometimes used in 3D model formats.

David Piuva 6 months ago
parent
commit
39c5678fea
3 changed files with 18 additions and 2 deletions
  1. 6 0
      Source/DFPSR/api/stringAPI.cpp
  2. 3 0
      Source/test/testTools.h
  3. 9 2
      Source/test/tests/StringTest.cpp

+ 6 - 0
Source/DFPSR/api/stringAPI.cpp

@@ -31,6 +31,7 @@
 #include <thread>
 #include <mutex>
 #include <stdexcept>
+#include <cmath>
 #include "stringAPI.h"
 #include "../api/fileAPI.h"
 #include "../settings.h"
@@ -1019,6 +1020,11 @@ double dsr::string_toDouble(const ReadableString& source) {
 			}
 		} else if (c == ',' || c == '.') {
 			reachedDecimal = true;
+		} else if (c == 'e' || c == 'E') {
+			// Apply the exponent after 'e'.
+			result *= std::pow(10.0, string_toInteger(string_after(source, i)));
+			// Skip remaining characters.
+			i = source.view.length;
 		}
 	}
 	if (negated) {

+ 3 - 0
Source/test/testTools.h

@@ -32,6 +32,9 @@ static thread_local String ExpectedErrorPrefix;
 inline bool OP_NEAR(float a, float b) {
 	return a > b - 0.0001f && a < b + 0.0001f;
 }
+inline bool OP_NEAR(double a, double b) {
+	return a > b - 0.0000001 && a < b + 0.0000001;
+}
 inline bool OP_NEAR(const FVector2D& a, const FVector2D& b) {
 	return OP_NEAR(a.x, b.x) && OP_NEAR(a.y, b.y);
 }

+ 9 - 2
Source/test/tests/StringTest.cpp

@@ -273,8 +273,15 @@ START_TEST(String)
 	ASSERT_EQUAL(string_toInteger(U"1000000"), 1000000);
 	ASSERT_EQUAL(string_toInteger(U"-1000000"), -1000000);
 	ASSERT_EQUAL(string_toInteger(U"123"), 123);
-	ASSERT_EQUAL(string_toDouble(U"123"), 123.0);
-	ASSERT_EQUAL(string_toDouble(U"123.456"), 123.456);
+	ASSERT_NEAR(string_toDouble(U"123"), 123.0);
+	ASSERT_NEAR(string_toDouble(U"123.456"), 123.456);
+	ASSERT_NEAR(string_toDouble(U"123.456e-3"), 0.123456);
+	ASSERT_NEAR(string_toDouble(U"123.456e-2"), 1.23456);
+	ASSERT_NEAR(string_toDouble(U"123.456e-1"), 12.3456);
+	ASSERT_NEAR(string_toDouble(U"123.456e0"), 123.456);
+	ASSERT_NEAR(string_toDouble(U"123.456e1"), 1234.56);
+	ASSERT_NEAR(string_toDouble(U"123.456e2"), 12345.6);
+	ASSERT_NEAR(string_toDouble(U"123.456e3"), 123456.0);
 	{ // Assigning strings using reference counting
 		String a = U"Some text";
 		ASSERT_EQUAL(string_getBufferUseCount(a), 1);