From 13939734e05e231f63e5bd7275d182491600e206 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 14 Jan 2022 21:17:01 -0600 Subject: Replace String::num_real code with a wrapper around String::num --- core/string/ustring.cpp | 113 ++++------------------------------------ tests/core/math/test_vector2.h | 19 +++++++ tests/core/math/test_vector3.h | 19 +++++++ tests/core/string/test_string.h | 8 ++- 4 files changed, 56 insertions(+), 103 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 0949980713..658dbc98cf 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1527,115 +1527,24 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) { } String String::num_real(double p_num, bool p_trailing) { - if (Math::is_nan(p_num)) { - return "nan"; - } - - if (Math::is_inf(p_num)) { - if (signbit(p_num)) { - return "-inf"; + if (p_num == (double)(int64_t)p_num) { + if (p_trailing) { + return num_int64((int64_t)p_num) + ".0"; } else { - return "inf"; + return num_int64((int64_t)p_num); } } - - String s; - String sd; - - // Integer part. - - bool neg = p_num < 0; - p_num = ABS(p_num); - int64_t intn = (int64_t)p_num; - - // Decimal part. - - if (intn != p_num) { - double dec = p_num - (double)intn; - - int digit = 0; - #ifdef REAL_T_IS_DOUBLE - int decimals = 14; - double tolerance = 1e-14; + int decimals = 14; #else - int decimals = 6; - double tolerance = 1e-6; + int decimals = 6; #endif - // We want to align the digits to the above sane default, so we only - // need to subtract log10 for numbers with a positive power of ten. - if (p_num > 10) { - decimals -= (int)floor(log10(p_num)); - } - - if (decimals > MAX_DECIMALS) { - decimals = MAX_DECIMALS; - } - - // In case the value ends up ending in "99999", we want to add a - // tiny bit to the value we're checking when deciding when to stop, - // so we multiply by slightly above 1 (1 + 1e-7 or 1e-15). - double check_multiplier = 1 + tolerance / 10; - - int64_t dec_int = 0; - int64_t dec_max = 0; - - while (true) { - dec *= 10.0; - dec_int = dec_int * 10 + (int64_t)dec % 10; - dec_max = dec_max * 10 + 9; - digit++; - - if ((dec - (double)(int64_t)(dec * check_multiplier)) < tolerance) { - break; - } - - if (digit == decimals) { - break; - } - } - - dec *= 10; - int last = (int64_t)dec % 10; - - if (last > 5) { - if (dec_int == dec_max) { - dec_int = 0; - intn++; - } else { - dec_int++; - } - } - - String decimal; - for (int i = 0; i < digit; i++) { - char num[2] = { 0, 0 }; - num[0] = '0' + dec_int % 10; - decimal = num + decimal; - dec_int /= 10; - } - sd = '.' + decimal; - } else if (p_trailing) { - sd = ".0"; - } else { - sd = ""; + // We want to align the digits to the above sane default, so we only + // need to subtract log10 for numbers with a positive power of ten. + if (p_num > 10) { + decimals -= (int)floor(log10(p_num)); } - - if (intn == 0) { - s = "0"; - } else { - while (intn) { - char32_t num = '0' + (intn % 10); - intn /= 10; - s = num + s; - } - } - - s = s + sd; - if (neg) { - s = "-" + s; - } - return s; + return num(p_num, decimals); } String String::num_scientific(double p_num) { diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h index 7dd14736e8..cb447acd17 100644 --- a/tests/core/math/test_vector2.h +++ b/tests/core/math/test_vector2.h @@ -246,6 +246,25 @@ TEST_CASE("[Vector2] Operators") { CHECK_MESSAGE( Vector2(Vector2i(1, 2)) == Vector2(1, 2), "Vector2 constructed from Vector2i should work as expected."); + + CHECK_MESSAGE( + ((String)decimal1) == "(2.3, 4.9)", + "Vector2 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)decimal2) == "(1.2, 3.4)", + "Vector2 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)Vector2(9.8, 9.9)) == "(9.8, 9.9)", + "Vector2 cast to String should work as expected."); +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE( + ((String)Vector2(Math_PI, Math_TAU)) == "(3.14159265358979, 6.28318530717959)", + "Vector2 cast to String should print the correct amount of digits for real_t = double."); +#else + CHECK_MESSAGE( + ((String)Vector2(Math_PI, Math_TAU)) == "(3.141593, 6.283185)", + "Vector2 cast to String should print the correct amount of digits for real_t = float."); +#endif // REAL_T_IS_DOUBLE } TEST_CASE("[Vector2] Other methods") { diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h index 97da035046..136a531946 100644 --- a/tests/core/math/test_vector3.h +++ b/tests/core/math/test_vector3.h @@ -271,6 +271,25 @@ TEST_CASE("[Vector3] Operators") { CHECK_MESSAGE( Vector3(Vector3i(1, 2, 3)) == Vector3(1, 2, 3), "Vector3 constructed from Vector3i should work as expected."); + + CHECK_MESSAGE( + ((String)decimal1) == "(2.3, 4.9, 7.8)", + "Vector3 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)decimal2) == "(1.2, 3.4, 5.6)", + "Vector3 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)Vector3(9.7, 9.8, 9.9)) == "(9.7, 9.8, 9.9)", + "Vector3 cast to String should work as expected."); +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE( + ((String)Vector3(Math_E, Math_SQRT2, Math_SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888)", + "Vector3 cast to String should print the correct amount of digits for real_t = double."); +#else + CHECK_MESSAGE( + ((String)Vector3(Math_E, Math_SQRT2, Math_SQRT3)) == "(2.718282, 1.414214, 1.732051)", + "Vector3 cast to String should print the correct amount of digits for real_t = float."); +#endif // REAL_T_IS_DOUBLE } TEST_CASE("[Vector3] Other methods") { diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 2f611c26a9..baab5ddfe7 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -355,11 +355,17 @@ TEST_CASE("[String] Number to string") { CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros. // String::num_real tests. + CHECK(String::num_real(1.0) == "1.0"); + CHECK(String::num_real(1.0, false) == "1"); + CHECK(String::num_real(9.9) == "9.9"); + CHECK(String::num_real(9.99) == "9.99"); + CHECK(String::num_real(9.999) == "9.999"); + CHECK(String::num_real(9.9999) == "9.9999"); CHECK(String::num_real(3.141593) == "3.141593"); CHECK(String::num_real(3.141) == "3.141"); // No trailing zeros. #ifdef REAL_T_IS_DOUBLE CHECK_MESSAGE(String::num_real(Math_PI) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double."); - CHECK_MESSAGE(String::num_real(3.1415f) == "3.14149999618530", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double)."); + CHECK_MESSAGE(String::num_real(3.1415f) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero."); #else CHECK_MESSAGE(String::num_real(Math_PI) == "3.141593", "Prints the appropriate amount of digits for real_t = float."); CHECK_MESSAGE(String::num_real(3.1415f) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float."); -- cgit v1.2.3