浏览代码

Always add decimal when printing float

kobewi 1 年之前
父节点
当前提交
5c0f2414cd
共有 31 个文件被更改,包括 240 次插入140 次删除
  1. 6 0
      core/extension/extension_api_dump.cpp
  2. 1 1
      core/math/rect2.cpp
  3. 1 1
      core/math/vector2.cpp
  4. 1 1
      core/math/vector3.cpp
  5. 21 7
      core/string/ustring.cpp
  6. 1 0
      core/string/ustring.h
  7. 1 1
      core/variant/variant.cpp
  8. 1 1
      modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out
  9. 5 5
      modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd
  10. 1 1
      modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out
  11. 15 15
      modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
  12. 15 15
      modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd
  13. 13 13
      modules/gdscript/tests/scripts/parser/features/export_arrays.out
  14. 3 3
      modules/gdscript/tests/scripts/parser/features/export_variable.out
  15. 1 1
      modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out
  16. 6 6
      modules/gdscript/tests/scripts/parser/features/number_separators.out
  17. 1 1
      modules/gdscript/tests/scripts/parser/features/operator_assign.out
  18. 6 6
      modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
  19. 3 3
      modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out
  20. 4 4
      modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out
  21. 8 8
      modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out
  22. 3 3
      modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out
  23. 11 11
      modules/gdscript/tests/scripts/runtime/features/stringify.out
  24. 0 1
      modules/gdscript/tests/scripts/utils.notest.gd
  25. 95 15
      modules/mono/editor/bindings_generator.cpp
  26. 1 1
      scene/gui/code_edit.cpp
  27. 1 1
      tests/core/math/test_aabb.h
  28. 1 1
      tests/core/math/test_color.h
  29. 1 1
      tests/core/math/test_rect2.h
  30. 12 12
      tests/core/string/test_string.h
  31. 1 1
      tests/core/variant/test_variant_utility.h

+ 6 - 0
core/extension/extension_api_dump.cpp

@@ -1371,6 +1371,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
 		Dictionary elem = var;
 		ERR_FAIL_COND_V_MSG(!elem.has(p_name_field), false, vformat("Validate extension JSON: Element of base_array '%s' is missing field '%s'. This is a bug.", base_array, p_name_field));
 		String name = elem[p_name_field];
+		if (name.is_valid_float()) {
+			name = name.trim_suffix(".0"); // Make "integers" stringified as integers.
+		}
 		if (p_compare_operators && elem.has("right_type")) {
 			name += " " + String(elem["right_type"]);
 		}
@@ -1386,6 +1389,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
 			continue;
 		}
 		String name = old_elem[p_name_field];
+		if (name.is_valid_float()) {
+			name = name.trim_suffix(".0"); // Make "integers" stringified as integers.
+		}
 		if (p_compare_operators && old_elem.has("right_type")) {
 			name += " " + String(old_elem["right_type"]);
 		}

+ 1 - 1
core/math/rect2.cpp

@@ -283,7 +283,7 @@ next4:
 }
 
 Rect2::operator String() const {
-	return "[P: " + position.operator String() + ", S: " + size + "]";
+	return "[P: " + position.operator String() + ", S: " + size.operator String() + "]";
 }
 
 Rect2::operator Rect2i() const {

+ 1 - 1
core/math/vector2.cpp

@@ -203,7 +203,7 @@ bool Vector2::is_finite() const {
 }
 
 Vector2::operator String() const {
-	return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")";
+	return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ")";
 }
 
 Vector2::operator Vector2i() const {

+ 1 - 1
core/math/vector3.cpp

@@ -165,7 +165,7 @@ bool Vector3::is_finite() const {
 }
 
 Vector3::operator String() const {
-	return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")";
+	return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ", " + String::num_real(z, true) + ")";
 }
 
 Vector3::operator Vector3i() const {

+ 21 - 7
core/string/ustring.cpp

@@ -1818,7 +1818,7 @@ String String::num(double p_num, int p_decimals) {
 #endif
 
 	buf[324] = 0;
-	//destroy trailing zeroes
+	// Destroy trailing zeroes, except one after period.
 	{
 		bool period = false;
 		int z = 0;
@@ -1835,7 +1835,7 @@ String String::num(double p_num, int p_decimals) {
 				if (buf[z] == '0') {
 					buf[z] = 0;
 				} else if (buf[z] == '.') {
-					buf[z] = 0;
+					buf[z + 1] = '0';
 					break;
 				} else {
 					break;
@@ -1924,14 +1924,28 @@ String String::num_real(double p_num, bool p_trailing) {
 			return num_int64((int64_t)p_num);
 		}
 	}
-#ifdef REAL_T_IS_DOUBLE
 	int decimals = 14;
-#else
+	// 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 magnitude.
+	const double abs_num = Math::abs(p_num);
+	if (abs_num > 10) {
+		decimals -= (int)floor(log10(abs_num));
+	}
+	return num(p_num, decimals);
+}
+
+String String::num_real(float p_num, bool p_trailing) {
+	if (p_num == (float)(int64_t)p_num) {
+		if (p_trailing) {
+			return num_int64((int64_t)p_num) + ".0";
+		} else {
+			return num_int64((int64_t)p_num);
+		}
+	}
 	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 magnitude.
-	double abs_num = Math::abs(p_num);
+	const float abs_num = Math::abs(p_num);
 	if (abs_num > 10) {
 		decimals -= (int)floor(log10(abs_num));
 	}
@@ -4601,7 +4615,7 @@ String String::humanize_size(uint64_t p_size) {
 	}
 
 	if (magnitude == 0) {
-		return String::num(p_size) + " " + RTR("B");
+		return String::num_uint64(p_size) + " " + RTR("B");
 	} else {
 		String suffix;
 		switch (magnitude) {

+ 1 - 0
core/string/ustring.h

@@ -332,6 +332,7 @@ public:
 	static String num(double p_num, int p_decimals = -1);
 	static String num_scientific(double p_num);
 	static String num_real(double p_num, bool p_trailing = true);
+	static String num_real(float p_num, bool p_trailing = true);
 	static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false);
 	static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false);
 	static String chr(char32_t p_char);

+ 1 - 1
core/variant/variant.cpp

@@ -1736,7 +1736,7 @@ String Variant::stringify(int recursion_count) const {
 		case INT:
 			return itos(_data._int);
 		case FLOAT:
-			return rtos(_data._float);
+			return String::num_real(_data._float, true);
 		case STRING:
 			return *reinterpret_cast<const String *>(_data._mem);
 		case VECTOR2:

+ 1 - 1
modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out

@@ -1,2 +1,2 @@
 GDTEST_OK
-0
+0.0

+ 5 - 5
modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd

@@ -7,17 +7,17 @@ const const_packed_ints: PackedFloat64Array = [52]
 
 func test():
 	Utils.check(typeof(const_float_int) == TYPE_FLOAT)
-	Utils.check(str(const_float_int) == '19')
+	Utils.check(str(const_float_int) == '19.0')
 	Utils.check(typeof(const_float_plus) == TYPE_FLOAT)
-	Utils.check(str(const_float_plus) == '34')
+	Utils.check(str(const_float_plus) == '34.0')
 	Utils.check(typeof(const_float_cast) == TYPE_FLOAT)
-	Utils.check(str(const_float_cast) == '76')
+	Utils.check(str(const_float_cast) == '76.0')
 
 	Utils.check(typeof(const_packed_empty) == TYPE_PACKED_FLOAT64_ARRAY)
 	Utils.check(str(const_packed_empty) == '[]')
 	Utils.check(typeof(const_packed_ints) == TYPE_PACKED_FLOAT64_ARRAY)
-	Utils.check(str(const_packed_ints) == '[52]')
+	Utils.check(str(const_packed_ints) == '[52.0]')
 	Utils.check(typeof(const_packed_ints[0]) == TYPE_FLOAT)
-	Utils.check(str(const_packed_ints[0]) == '52')
+	Utils.check(str(const_packed_ints[0]) == '52.0')
 
 	print('ok')

+ 1 - 1
modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out

@@ -1,2 +1,2 @@
 GDTEST_OK
-4
+4.0

+ 15 - 15
modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd

@@ -54,39 +54,39 @@ func test():
 	untyped_basic.push_back(430.0)
 	inferred_basic.push_back(263.0)
 	typed_basic.push_back(518.0)
-	Utils.check(str(empty_floats) == '[705, 430, 263, 518]')
-	Utils.check(str(untyped_basic) == '[705, 430, 263, 518]')
-	Utils.check(str(inferred_basic) == '[705, 430, 263, 518]')
-	Utils.check(str(typed_basic) == '[705, 430, 263, 518]')
+	Utils.check(str(empty_floats) == '[705.0, 430.0, 263.0, 518.0]')
+	Utils.check(str(untyped_basic) == '[705.0, 430.0, 263.0, 518.0]')
+	Utils.check(str(inferred_basic) == '[705.0, 430.0, 263.0, 518.0]')
+	Utils.check(str(typed_basic) == '[705.0, 430.0, 263.0, 518.0]')
 
 
 	const constant_float := 950.0
 	const constant_int := 170
 	var typed_float := 954.0
 	var filled_floats: Array[float] = [constant_float, constant_int, typed_float, empty_floats[1] + empty_floats[2]]
-	Utils.check(str(filled_floats) == '[950, 170, 954, 693]')
+	Utils.check(str(filled_floats) == '[950.0, 170.0, 954.0, 693.0]')
 	Utils.check(filled_floats.get_typed_builtin() == TYPE_FLOAT)
 
 	var casted_floats := [empty_floats[2] * 2] as Array[float]
-	Utils.check(str(casted_floats) == '[526]')
+	Utils.check(str(casted_floats) == '[526.0]')
 	Utils.check(casted_floats.get_typed_builtin() == TYPE_FLOAT)
 
 	var returned_floats = (func () -> Array[float]: return [554]).call()
-	Utils.check(str(returned_floats) == '[554]')
+	Utils.check(str(returned_floats) == '[554.0]')
 	Utils.check(returned_floats.get_typed_builtin() == TYPE_FLOAT)
 
 	var passed_floats = floats_identity([663.0 if randf() > 0.5 else 663.0])
-	Utils.check(str(passed_floats) == '[663]')
+	Utils.check(str(passed_floats) == '[663.0]')
 	Utils.check(passed_floats.get_typed_builtin() == TYPE_FLOAT)
 
 	var default_floats = (func (floats: Array[float] = [364.0]): return floats).call()
-	Utils.check(str(default_floats) == '[364]')
+	Utils.check(str(default_floats) == '[364.0]')
 	Utils.check(default_floats.get_typed_builtin() == TYPE_FLOAT)
 
 	var typed_int := 556
 	var converted_floats: Array[float] = [typed_int]
 	converted_floats.push_back(498)
-	Utils.check(str(converted_floats) == '[556, 498]')
+	Utils.check(str(converted_floats) == '[556.0, 498.0]')
 	Utils.check(converted_floats.get_typed_builtin() == TYPE_FLOAT)
 
 
@@ -95,7 +95,7 @@ func test():
 	Utils.check(constant_basic.get_typed_builtin() == TYPE_NIL)
 
 	const constant_floats: Array[float] = [constant_float - constant_basic[0] - constant_int]
-	Utils.check(str(constant_floats) == '[552]')
+	Utils.check(str(constant_floats) == '[552.0]')
 	Utils.check(constant_floats.get_typed_builtin() == TYPE_FLOAT)
 
 
@@ -103,15 +103,15 @@ func test():
 	untyped_basic = source_floats
 	var destination_floats: Array[float] = untyped_basic
 	destination_floats[0] -= 0.74
-	Utils.check(str(source_floats) == '[999]')
-	Utils.check(str(untyped_basic) == '[999]')
-	Utils.check(str(destination_floats) == '[999]')
+	Utils.check(str(source_floats) == '[999.0]')
+	Utils.check(str(untyped_basic) == '[999.0]')
+	Utils.check(str(destination_floats) == '[999.0]')
 	Utils.check(destination_floats.get_typed_builtin() == TYPE_FLOAT)
 
 
 	var duplicated_floats := empty_floats.duplicate().slice(2, 3)
 	duplicated_floats[0] *= 3
-	Utils.check(str(duplicated_floats) == '[789]')
+	Utils.check(str(duplicated_floats) == '[789.0]')
 	Utils.check(duplicated_floats.get_typed_builtin() == TYPE_FLOAT)
 
 

+ 15 - 15
modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd

@@ -62,44 +62,44 @@ func test():
 	untyped_basic[430.0] = 34.0
 	inferred_basic[263.0] = 362.0
 	typed_basic[518.0] = 815.0
-	Utils.check(str(empty_floats) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }')
-	Utils.check(str(untyped_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }')
-	Utils.check(str(inferred_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }')
-	Utils.check(str(typed_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }')
+	Utils.check(str(empty_floats) == '{ 705.0: 507.0, 430.0: 34.0, 263.0: 362.0, 518.0: 815.0 }')
+	Utils.check(str(untyped_basic) == '{ 705.0: 507.0, 430.0: 34.0, 263.0: 362.0, 518.0: 815.0 }')
+	Utils.check(str(inferred_basic) == '{ 705.0: 507.0, 430.0: 34.0, 263.0: 362.0, 518.0: 815.0 }')
+	Utils.check(str(typed_basic) == '{ 705.0: 507.0, 430.0: 34.0, 263.0: 362.0, 518.0: 815.0 }')
 
 
 	const constant_float := 950.0
 	const constant_int := 170
 	var typed_float := 954.0
 	var filled_floats: Dictionary[float, float] = { constant_float: constant_int, typed_float: empty_floats[430.0] + empty_floats[263.0] }
-	Utils.check(str(filled_floats) == '{ 950: 170, 954: 396 }')
+	Utils.check(str(filled_floats) == '{ 950.0: 170.0, 954.0: 396.0 }')
 	Utils.check(filled_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(filled_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
 	var casted_floats := { empty_floats[263.0] * 2: empty_floats[263.0] / 2 } as Dictionary[float, float]
-	Utils.check(str(casted_floats) == '{ 724: 181 }')
+	Utils.check(str(casted_floats) == '{ 724.0: 181.0 }')
 	Utils.check(casted_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(casted_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
 	var returned_floats = (func () -> Dictionary[float, float]: return { 554: 455 }).call()
-	Utils.check(str(returned_floats) == '{ 554: 455 }')
+	Utils.check(str(returned_floats) == '{ 554.0: 455.0 }')
 	Utils.check(returned_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(returned_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
 	var passed_floats = floats_identity({ 663.0 if randf() > 0.5 else 663.0: 366.0 if randf() <= 0.5 else 366.0 })
-	Utils.check(str(passed_floats) == '{ 663: 366 }')
+	Utils.check(str(passed_floats) == '{ 663.0: 366.0 }')
 	Utils.check(passed_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(passed_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
 	var default_floats = (func (floats: Dictionary[float, float] = { 364.0: 463.0 }): return floats).call()
-	Utils.check(str(default_floats) == '{ 364: 463 }')
+	Utils.check(str(default_floats) == '{ 364.0: 463.0 }')
 	Utils.check(default_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(default_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
 	var typed_int := 556
 	var converted_floats: Dictionary[float, float] = { typed_int: typed_int }
 	converted_floats[498.0] = 894
-	Utils.check(str(converted_floats) == '{ 556: 556, 498: 894 }')
+	Utils.check(str(converted_floats) == '{ 556.0: 556.0, 498.0: 894.0 }')
 	Utils.check(converted_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(converted_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
@@ -110,7 +110,7 @@ func test():
 	Utils.check(constant_basic.get_typed_value_builtin() == TYPE_NIL)
 
 	const constant_floats: Dictionary[float, float] = { constant_float - constant_basic[228] - constant_int: constant_float + constant_basic[228] + constant_int }
-	Utils.check(str(constant_floats) == '{ -42: 1942 }')
+	Utils.check(str(constant_floats) == '{ -42.0: 1942.0 }')
 	Utils.check(constant_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(constant_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
@@ -119,9 +119,9 @@ func test():
 	untyped_basic = source_floats
 	var destination_floats: Dictionary[float, float] = untyped_basic
 	destination_floats[999.74] -= 0.999
-	Utils.check(str(source_floats) == '{ 999.74: 47 }')
-	Utils.check(str(untyped_basic) == '{ 999.74: 47 }')
-	Utils.check(str(destination_floats) == '{ 999.74: 47 }')
+	Utils.check(str(source_floats) == '{ 999.74: 47.0 }')
+	Utils.check(str(untyped_basic) == '{ 999.74: 47.0 }')
+	Utils.check(str(destination_floats) == '{ 999.74: 47.0 }')
 	Utils.check(destination_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(destination_floats.get_typed_value_builtin() == TYPE_FLOAT)
 
@@ -131,7 +131,7 @@ func test():
 	duplicated_floats.erase(430.0)
 	duplicated_floats.erase(518.0)
 	duplicated_floats[263.0] *= 3
-	Utils.check(str(duplicated_floats) == '{ 263: 1086 }')
+	Utils.check(str(duplicated_floats) == '{ 263.0: 1086.0 }')
 	Utils.check(duplicated_floats.get_typed_key_builtin() == TYPE_FLOAT)
 	Utils.check(duplicated_floats.get_typed_value_builtin() == TYPE_FLOAT)
 

+ 13 - 13
modules/gdscript/tests/scripts/parser/features/export_arrays.out

@@ -80,21 +80,21 @@ var test_placeholder: Array
 var test_placeholder_packed: PackedStringArray
   hint=TYPE_STRING hint_string="<String>/<PLACEHOLDER_TEXT>:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_int: Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_int_packed_byte: PackedByteArray
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_int_packed32: PackedInt32Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_int_packed64: PackedInt64Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_int_float_step: Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10,0.01" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0,0.01" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_float: Array
-  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<float>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_float_packed32: PackedFloat32Array
-  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<float>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_float_packed64: PackedFloat64Array
-  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<float>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_exp_easing: Array
   hint=TYPE_STRING hint_string="<float>/<EXP_EASING>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_exp_easing_packed32: PackedFloat32Array
@@ -126,14 +126,14 @@ var test_weak_packed_vector3_array: PackedVector3Array
 var test_weak_packed_vector4_array: PackedVector4Array
   hint=TYPE_STRING hint_string="<Vector4>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_weak_packed_byte_array: PackedByteArray
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_weak_packed_int32_array: PackedInt32Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_weak_packed_int64_array: PackedInt64Array
-  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<int>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_weak_packed_float32_array: PackedFloat32Array
-  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<float>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_weak_packed_float64_array: PackedFloat64Array
-  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=TYPE_STRING hint_string="<float>/<RANGE>:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_noalpha_weak_packed_color_array: PackedColorArray
   hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""

+ 3 - 3
modules/gdscript/tests/scripts/parser/features/export_variable.out

@@ -4,11 +4,11 @@ var test_weak_int: int = 1
 var test_hard_int: int = 2
   hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range: int = 100
-  hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=RANGE hint_string="0.0,100.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_step: int = 101
-  hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=RANGE hint_string="0.0,100.0,1.0" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_range_step_or_greater: int = 102
-  hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+  hint=RANGE hint_string="0.0,100.0,1.0,or_greater" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_color: Color = Color(0, 0, 0, 1)
   hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
 var test_color_no_alpha: Color = Color(0, 0, 0, 1)

+ 1 - 1
modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out

@@ -13,4 +13,4 @@ true
 0
 -255
 256
-2
+2.0

+ 6 - 6
modules/gdscript/tests/scripts/parser/features/number_separators.out

@@ -13,12 +13,12 @@ GDTEST_OK
 ---
 -1234.4567
 -1234.4567
--1234
--1234
+-1234.0
+-1234.0
 0.4567
 0.4567
 ---
--1234500
--1234500
--1234500
--1234500
+-1234500.0
+-1234500.0
+-1234500.0
+-1234500.0

+ 1 - 1
modules/gdscript/tests/scripts/parser/features/operator_assign.out

@@ -1,2 +1,2 @@
 GDTEST_OK
-8
+8.0

+ 6 - 6
modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out

@@ -1,7 +1,7 @@
 GDTEST_OK
-{ 1: (2, 0) }
-{ 3: (4, 0) }
-[[(5, 0)]]
-[[(6, 0)]]
-[[(7, 0)]]
-[X: (8, 9, 7), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)]
+{ 1: (2.0, 0.0) }
+{ 3: (4.0, 0.0) }
+[[(5.0, 0.0)]]
+[[(6.0, 0.0)]]
+[[(7.0, 0.0)]]
+[X: (8.0, 9.0, 7.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0), O: (0.0, 0.0, 0.0)]

+ 3 - 3
modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out

@@ -1,8 +1,8 @@
 GDTEST_OK
-x is 1
+x is 1.0
 typeof x is 3
-x is 2
+x is 2.0
 typeof x is 3
-x is 3
+x is 3.0
 typeof x is 3
 ok

+ 4 - 4
modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out

@@ -11,7 +11,7 @@ a
 1
 b
 1
-(1, 1)
-(0, 0)
-(6, 1)
-(0, 0)
+(1.0, 1.0)
+(0.0, 0.0)
+(6.0, 1.0)
+(0.0, 0.0)

+ 8 - 8
modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out

@@ -1,26 +1,26 @@
 GDTEST_OK
 ===
-prop1 setter (0, 0)
-prop1 setter (1, 0)
+prop1 setter (0.0, 0.0)
+prop1 setter (1.0, 0.0)
 ---
 prop1 setter <Inner>
 subprop getter
-subprop setter (1, 0)
+subprop setter (1.0, 0.0)
 ===
 prop2 setter <Inner>
 subprop getter
-subprop setter (1, 0)
+subprop setter (1.0, 0.0)
 ===
-prop3 setter (0, 0)
+prop3 setter (0.0, 0.0)
 prop3 getter
-prop3 setter (1, 0)
+prop3 setter (1.0, 0.0)
 ---
 prop3 setter <Inner>
 prop3 getter
 subprop getter
-subprop setter (1, 0)
+subprop setter (1.0, 0.0)
 ===
 prop4 setter <Inner>
 prop4 getter
 subprop getter
-subprop setter (1, 0)
+subprop setter (1.0, 0.0)

+ 3 - 3
modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out

@@ -1,4 +1,4 @@
 GDTEST_OK
-setting vec from (0, 0) to (2, 0)
-setting vec from (0, 0) to (0, 2)
-vec is (0, 0)
+setting vec from (0.0, 0.0) to (2.0, 0.0)
+setting vec from (0.0, 0.0) to (0.0, 2.0)
+vec is (0.0, 0.0)

+ 11 - 11
modules/gdscript/tests/scripts/runtime/features/stringify.out

@@ -9,13 +9,13 @@ hello world
 [P: (0, 0), S: (0, 0)]
 (0.25, 0.25, 0.25)
 (0, 0, 0)
-[X: (1, 0), Y: (0, 1), O: (0, 0)]
-[N: (1, 2, 3), D: 4]
-(1, 2, 3, 4)
-[P: (0, 0, 0), S: (1, 1, 1)]
-[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1)]
-[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)]
+[X: (1.0, 0.0), Y: (0.0, 1.0), O: (0.0, 0.0)]
+[N: (1.0, 2.0, 3.0), D: 4]
 (1, 2, 3, 4)
+[P: (0.0, 0.0, 0.0), S: (1.0, 1.0, 1.0)]
+[X: (1.0, 0.0, 0.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0)]
+[X: (1.0, 0.0, 0.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0), O: (0.0, 0.0, 0.0)]
+(1.0, 2.0, 3.0, 4.0)
 hello
 hello/world
 RID(0)
@@ -26,10 +26,10 @@ Node::[signal]property_list_changed
 [255, 0, 1]
 [-1, 0, 1]
 [-1, 0, 1]
-[-1, 0, 1]
-[-1, 0, 1]
+[-1.0, 0.0, 1.0]
+[-1.0, 0.0, 1.0]
 ["hello", "world"]
-[(1, 1), (0, 0)]
-[(1, 1, 1), (0, 0, 0)]
-[(1, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1)]
+[(1.0, 1.0), (0.0, 0.0)]
+[(1.0, 1.0, 1.0), (0.0, 0.0, 0.0)]
+[(1.0, 0.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (0.0, 1.0, 0.0, 1.0)]
 [(1, 1, 1, 1), (0, 0, 0, 0)]

+ 0 - 1
modules/gdscript/tests/scripts/utils.notest.gd

@@ -1,6 +1,5 @@
 class_name Utils
 
-
 # `assert()` is not evaluated in non-debug builds. Do not use `assert()`
 # for anything other than testing the `assert()` itself.
 static func check(condition: Variant) -> void:

+ 95 - 15
modules/mono/editor/bindings_generator.cpp

@@ -4372,9 +4372,45 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
 	return true;
 }
 
+static String _get_vector2_cs_ctor_args(const Vector2 &p_vec2) {
+	return String::num_real(p_vec2.x, true) + "f, " +
+			String::num_real(p_vec2.y, true) + "f";
+}
+
+static String _get_vector3_cs_ctor_args(const Vector3 &p_vec3) {
+	return String::num_real(p_vec3.x, true) + "f, " +
+			String::num_real(p_vec3.y, true) + "f, " +
+			String::num_real(p_vec3.z, true) + "f";
+}
+
+static String _get_vector4_cs_ctor_args(const Vector4 &p_vec4) {
+	return String::num_real(p_vec4.x, true) + "f, " +
+			String::num_real(p_vec4.y, true) + "f, " +
+			String::num_real(p_vec4.z, true) + "f, " +
+			String::num_real(p_vec4.w, true) + "f";
+}
+
+static String _get_vector2i_cs_ctor_args(const Vector2i &p_vec2i) {
+	return itos(p_vec2i.x) + ", " + itos(p_vec2i.y);
+}
+
+static String _get_vector3i_cs_ctor_args(const Vector3i &p_vec3i) {
+	return itos(p_vec3i.x) + ", " + itos(p_vec3i.y) + ", " + itos(p_vec3i.z);
+}
+
+static String _get_vector4i_cs_ctor_args(const Vector4i &p_vec4i) {
+	return itos(p_vec4i.x) + ", " + itos(p_vec4i.y) + ", " + itos(p_vec4i.z) + ", " + itos(p_vec4i.w);
+}
+
+static String _get_color_cs_ctor_args(const Color &p_color) {
+	return String::num(p_color.r, 4) + "f, " +
+			String::num(p_color.g, 4) + "f, " +
+			String::num(p_color.b, 4) + "f, " +
+			String::num(p_color.a, 4) + "f";
+}
+
 bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg) {
 	r_iarg.def_param_value = p_val;
-	r_iarg.default_argument = p_val.operator String();
 
 	switch (p_val.get_type()) {
 		case Variant::NIL:
@@ -4387,10 +4423,14 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 			break;
 		case Variant::INT:
 			if (r_iarg.type.cname != name_cache.type_int) {
-				r_iarg.default_argument = "(%s)(" + r_iarg.default_argument + ")";
+				r_iarg.default_argument = "(%s)(" + p_val.operator String() + ")";
+			} else {
+				r_iarg.default_argument = p_val.operator String();
 			}
 			break;
 		case Variant::FLOAT:
+			r_iarg.default_argument = p_val.operator String();
+
 			if (r_iarg.type.cname == name_cache.type_float) {
 				r_iarg.default_argument += "f";
 			}
@@ -4400,7 +4440,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 		case Variant::NODE_PATH:
 			if (r_iarg.type.cname == name_cache.type_StringName || r_iarg.type.cname == name_cache.type_NodePath) {
 				if (r_iarg.default_argument.length() > 0) {
-					r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\"";
+					r_iarg.default_argument = "(%s)\"" + p_val.operator String() + "\"";
 					r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
 				} else {
 					// No need for a special `in` statement to change `null` to `""`. Marshaling takes care of this already.
@@ -4408,40 +4448,62 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 				}
 			} else {
 				CRASH_COND(r_iarg.type.cname != name_cache.type_String);
-				r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
+				r_iarg.default_argument = "\"" + p_val.operator String() + "\"";
 			}
 			break;
 		case Variant::PLANE: {
 			Plane plane = p_val.operator Plane();
-			r_iarg.default_argument = "new Plane(new Vector3" + plane.normal.operator String() + ", " + rtos(plane.d) + ")";
+			r_iarg.default_argument = "new Plane(new Vector3(" +
+					_get_vector3_cs_ctor_args(plane.normal) + "), " + rtos(plane.d) + "f)";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
 		case Variant::AABB: {
 			AABB aabb = p_val.operator ::AABB();
-			r_iarg.default_argument = "new Aabb(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")";
+			r_iarg.default_argument = "new Aabb(new Vector3(" +
+					_get_vector3_cs_ctor_args(aabb.position) + "), new Vector3(" +
+					_get_vector3_cs_ctor_args(aabb.size) + "))";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
 		case Variant::RECT2: {
 			Rect2 rect = p_val.operator Rect2();
-			r_iarg.default_argument = "new Rect2(new Vector2" + rect.position.operator String() + ", new Vector2" + rect.size.operator String() + ")";
+			r_iarg.default_argument = "new Rect2(new Vector2(" +
+					_get_vector2_cs_ctor_args(rect.position) + "), new Vector2(" +
+					_get_vector2_cs_ctor_args(rect.size) + "))";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
 		case Variant::RECT2I: {
 			Rect2i rect = p_val.operator Rect2i();
-			r_iarg.default_argument = "new Rect2I(new Vector2I" + rect.position.operator String() + ", new Vector2I" + rect.size.operator String() + ")";
+			r_iarg.default_argument = "new Rect2I(new Vector2I(" +
+					_get_vector2i_cs_ctor_args(rect.position) + "), new Vector2I(" +
+					_get_vector2i_cs_ctor_args(rect.size) + "))";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
 		case Variant::COLOR:
+			r_iarg.default_argument = "new Color(" + _get_color_cs_ctor_args(p_val.operator Color()) + ")";
+			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+			break;
 		case Variant::VECTOR2:
+			r_iarg.default_argument = "new Vector2(" + _get_vector2_cs_ctor_args(p_val.operator Vector2()) + ")";
+			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+			break;
 		case Variant::VECTOR2I:
+			r_iarg.default_argument = "new Vector2I(" + _get_vector2i_cs_ctor_args(p_val.operator Vector2i()) + ")";
+			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+			break;
 		case Variant::VECTOR3:
+			r_iarg.default_argument = "new Vector3(" + _get_vector3_cs_ctor_args(p_val.operator Vector3()) + ")";
+			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+			break;
 		case Variant::VECTOR3I:
-			r_iarg.default_argument = "new %s" + r_iarg.default_argument;
+			r_iarg.default_argument = "new Vector3I(" + _get_vector3i_cs_ctor_args(p_val.operator Vector3i()) + ")";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 			break;
 		case Variant::VECTOR4:
+			r_iarg.default_argument = "new Vector4(" + _get_vector4_cs_ctor_args(p_val.operator Vector4()) + ")";
+			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+			break;
 		case Variant::VECTOR4I:
-			r_iarg.default_argument = "new %s" + r_iarg.default_argument;
+			r_iarg.default_argument = "new Vector4I(" + _get_vector4i_cs_ctor_args(p_val.operator Vector4i()) + ")";
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 			break;
 		case Variant::OBJECT:
@@ -4491,7 +4553,10 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 			if (transform == Transform2D()) {
 				r_iarg.default_argument = "Transform2D.Identity";
 			} else {
-				r_iarg.default_argument = "new Transform2D(new Vector2" + transform.columns[0].operator String() + ", new Vector2" + transform.columns[1].operator String() + ", new Vector2" + transform.columns[2].operator String() + ")";
+				r_iarg.default_argument = "new Transform2D(new Vector2(" +
+						_get_vector2_cs_ctor_args(transform.columns[0]) + "), new Vector2(" +
+						_get_vector2_cs_ctor_args(transform.columns[1]) + "), new Vector2(" +
+						_get_vector2_cs_ctor_args(transform.columns[2]) + "))";
 			}
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
@@ -4501,7 +4566,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 				r_iarg.default_argument = "Transform3D.Identity";
 			} else {
 				Basis basis = transform.basis;
-				r_iarg.default_argument = "new Transform3D(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")";
+				r_iarg.default_argument = "new Transform3D(new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(0)) + "), new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(1)) + "), new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(2)) + "), new Vector3(" +
+						_get_vector3_cs_ctor_args(transform.origin) + "))";
 			}
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
@@ -4510,7 +4579,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 			if (projection == Projection()) {
 				r_iarg.default_argument = "Projection.Identity";
 			} else {
-				r_iarg.default_argument = "new Projection(new Vector4" + projection.columns[0].operator String() + ", new Vector4" + projection.columns[1].operator String() + ", new Vector4" + projection.columns[2].operator String() + ", new Vector4" + projection.columns[3].operator String() + ")";
+				r_iarg.default_argument = "new Projection(new Vector4(" +
+						_get_vector4_cs_ctor_args(projection.columns[0]) + "), new Vector4(" +
+						_get_vector4_cs_ctor_args(projection.columns[1]) + "), new Vector4(" +
+						_get_vector4_cs_ctor_args(projection.columns[2]) + "), new Vector4(" +
+						_get_vector4_cs_ctor_args(projection.columns[3]) + "))";
 			}
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
@@ -4519,7 +4592,10 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 			if (basis == Basis()) {
 				r_iarg.default_argument = "Basis.Identity";
 			} else {
-				r_iarg.default_argument = "new Basis(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ")";
+				r_iarg.default_argument = "new Basis(new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(0)) + "), new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(1)) + "), new Vector3(" +
+						_get_vector3_cs_ctor_args(basis.get_column(2)) + "))";
 			}
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;
@@ -4528,7 +4604,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
 			if (quaternion == Quaternion()) {
 				r_iarg.default_argument = "Quaternion.Identity";
 			} else {
-				r_iarg.default_argument = "new Quaternion" + quaternion.operator String();
+				r_iarg.default_argument = "new Quaternion(" +
+						String::num_real(quaternion.x, false) + "f, " +
+						String::num_real(quaternion.y, false) + "f, " +
+						String::num_real(quaternion.z, false) + "f, " +
+						String::num_real(quaternion.w, false) + "f)";
 			}
 			r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
 		} break;

+ 1 - 1
scene/gui/code_edit.cpp

@@ -1481,7 +1481,7 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2
 	if (E) {
 		text_rid = E->value;
 	} else {
-		String fc = String::num(p_line + 1).lpad(line_number_digits, line_number_padding);
+		String fc = String::num_int64(p_line + 1).lpad(line_number_digits, line_number_padding);
 		if (is_localizing_numeral_system()) {
 			fc = TS->format_number(fc);
 		}

+ 1 - 1
tests/core/math/test_aabb.h

@@ -48,7 +48,7 @@ TEST_CASE("[AABB] Constructor methods") {
 
 TEST_CASE("[AABB] String conversion") {
 	CHECK_MESSAGE(
-			String(AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6))) == "[P: (-1.5, 2, -2.5), S: (4, 5, 6)]",
+			String(AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6))) == "[P: (-1.5, 2.0, -2.5), S: (4.0, 5.0, 6.0)]",
 			"The string representation should match the expected value.");
 }
 

+ 1 - 1
tests/core/math/test_color.h

@@ -140,7 +140,7 @@ TEST_CASE("[Color] Conversion methods") {
 			cyan.to_rgba64() == 0x0000'ffff'ffff'ffff,
 			"The returned 64-bit BGR number should match the expected value.");
 	CHECK_MESSAGE(
-			String(cyan) == "(0, 1, 1, 1)",
+			String(cyan) == "(0.0, 1.0, 1.0, 1.0)",
 			"The string representation should match the expected value.");
 }
 

+ 1 - 1
tests/core/math/test_rect2.h

@@ -57,7 +57,7 @@ TEST_CASE("[Rect2] Constructor methods") {
 TEST_CASE("[Rect2] String conversion") {
 	// Note: This also depends on the Vector2 string representation.
 	CHECK_MESSAGE(
-			String(Rect2(0, 100, 1280, 720)) == "[P: (0, 100), S: (1280, 720)]",
+			String(Rect2(0, 100, 1280, 720)) == "[P: (0.0, 100.0), S: (1280.0, 720.0)]",
 			"The string representation should match the expected value.");
 }
 

+ 12 - 12
tests/core/string/test_string.h

@@ -455,9 +455,9 @@ TEST_CASE("[String] Erasing") {
 }
 
 TEST_CASE("[String] Number to string") {
-	CHECK(String::num(0) == "0");
-	CHECK(String::num(0.0) == "0"); // No trailing zeros.
-	CHECK(String::num(-0.0) == "-0"); // Includes sign even for zero.
+	CHECK(String::num(0) == "0.0"); // The method takes double, so always add zeros.
+	CHECK(String::num(0.0) == "0.0");
+	CHECK(String::num(-0.0) == "-0.0"); // Includes sign even for zero.
 	CHECK(String::num(3.141593) == "3.141593");
 	CHECK(String::num(3.141593, 3) == "3.142");
 	CHECK(String::num_scientific(30000000) == "3e+07");
@@ -476,15 +476,15 @@ TEST_CASE("[String] Number to string") {
 	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(123.456789) == "123.456789", "Prints the appropriate amount of digits for real_t = double.");
-	CHECK_MESSAGE(String::num_real(-123.456789) == "-123.456789", "Prints the appropriate amount of digits for real_t = 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.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero.");
+	CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.456789", "Prints the appropriate amount of digits for real_t = double.");
+	CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.456789", "Prints the appropriate amount of digits for real_t = double.");
+	CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double.");
+	CHECK_MESSAGE(String::num_real(real_t(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(123.456789) == "123.4568", "Prints the appropriate amount of digits for real_t = float.");
-	CHECK_MESSAGE(String::num_real(-123.456789) == "-123.4568", "Prints the appropriate amount of digits for real_t = float.");
-	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.");
+	CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.4568", "Prints the appropriate amount of digits for real_t = float.");
+	CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.4568", "Prints the appropriate amount of digits for real_t = float.");
+	CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.141593", "Prints the appropriate amount of digits for real_t = float.");
+	CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float.");
 #endif // REAL_T_IS_DOUBLE
 
 	// Checks doubles with many decimal places.
@@ -493,7 +493,7 @@ TEST_CASE("[String] Number to string") {
 	CHECK(String::num(-0.0000012345432123454321) == "-0.00000123454321");
 	CHECK(String::num(-10000.0000012345432123454321) == "-10000.0000012345");
 	CHECK(String::num(0.0000000000012345432123454321) == "0.00000000000123");
-	CHECK(String::num(0.0000000000012345432123454321, 3) == "0");
+	CHECK(String::num(0.0000000000012345432123454321, 3) == "0.0");
 
 	// Note: When relevant (remainder > 0.5), the last digit gets rounded up,
 	// which can also lead to not include a trailing zero, e.g. "...89" -> "...9".

+ 1 - 1
tests/core/variant/test_variant_utility.h

@@ -89,7 +89,7 @@ TEST_CASE("[VariantUtility] Type conversion") {
 
 		converted = VariantUtilityFunctions::type_convert(basis, Variant::Type::STRING);
 		CHECK(converted.get_type() == Variant::Type::STRING);
-		CHECK(converted == Variant("[X: (1.2, 0, 0), Y: (0, 3.4, 0), Z: (0, 0, 5.6)]"));
+		CHECK(converted == Variant("[X: (1.2, 0.0, 0.0), Y: (0.0, 3.4, 0.0), Z: (0.0, 0.0, 5.6)]"));
 	}
 
 	{