From 2b3bbde6dae2e251b1805b4dc731a18f5cb33629 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Tue, 5 Sep 2023 09:31:29 +0300
Subject: [PATCH] [String] Fix string conversion for -0.0 float values.

---
 core/string/ustring.cpp         | 10 +++++-----
 tests/core/string/test_string.h | 16 ++++++++++++++++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 3f11459a1e2..f6a17cf1a74 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1493,9 +1493,9 @@ String String::num(double p_num, int p_decimals) {
 
 	if (p_decimals < 0) {
 		p_decimals = 14;
-		const double abs_num = ABS(p_num);
+		const double abs_num = Math::abs(p_num);
 		if (abs_num > 10) {
-			// We want to align the digits to the above sane default, so we only
+			// We want to align the digits to the above reasonable default, so we only
 			// need to subtract log10 for numbers with a positive power of ten.
 			p_decimals -= (int)floor(log10(abs_num));
 		}
@@ -4890,8 +4890,8 @@ String String::sprintf(const Array &values, bool *error) const {
 					}
 
 					double value = values[value_index];
-					bool is_negative = (value < 0);
-					String str = String::num(ABS(value), min_decimals);
+					bool is_negative = signbit(value);
+					String str = String::num(Math::abs(value), min_decimals);
 					const bool is_finite = Math::is_finite(value);
 
 					// Pad decimals out.
@@ -4953,7 +4953,7 @@ String String::sprintf(const Array &values, bool *error) const {
 					String str = "(";
 					for (int i = 0; i < count; i++) {
 						double val = vec[i];
-						String number_str = String::num(ABS(val), min_decimals);
+						String number_str = String::num(Math::abs(val), min_decimals);
 						const bool is_finite = Math::is_finite(val);
 
 						// Pad decimals out.
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index 659fb003d35..c10ad6e13d1 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -805,6 +805,22 @@ TEST_CASE("[String] sprintf") {
 	REQUIRE(error == false);
 	CHECK(output == String("fish +99.990000 frog"));
 
+	// Real with sign (negative zero).
+	format = "fish %+f frog";
+	args.clear();
+	args.push_back(-0.0);
+	output = format.sprintf(args, &error);
+	REQUIRE(error == false);
+	CHECK(output == String("fish -0.000000 frog"));
+
+	// Real with sign (positive zero).
+	format = "fish %+f frog";
+	args.clear();
+	args.push_back(0.0);
+	output = format.sprintf(args, &error);
+	REQUIRE(error == false);
+	CHECK(output == String("fish +0.000000 frog"));
+
 	// Real with 1 decimal.
 	format = "fish %.1f frog";
 	args.clear();