summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-01-17 16:55:34 +0100
committerGitHub <noreply@github.com>2022-01-17 16:55:34 +0100
commit24f8a5979c5cfab3f7b3bccdfb27973918d3ae0c (patch)
tree8c68dbbdacd2a7e028d4a0e12007c0c331abca09
parentb315295ffcd53b74af8c36fa2abac5e957f88613 (diff)
parent13939734e05e231f63e5bd7275d182491600e206 (diff)
Merge pull request #56809 from aaronfranke/replace-num-real
-rw-r--r--core/string/ustring.cpp113
-rw-r--r--tests/core/math/test_vector2.h19
-rw-r--r--tests/core/math/test_vector3.h19
-rw-r--r--tests/core/string/test_string.h8
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.");