You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Use num_scientific (Grisu2) when stringifying JSON with full precision
This commit is contained in:
@@ -82,11 +82,18 @@ void JSON::_stringify(String &r_result, const Variant &p_var, const String &p_in
|
||||
return;
|
||||
}
|
||||
|
||||
const double magnitude = std::log10(Math::abs(num));
|
||||
const int total_digits = p_full_precision ? 17 : 14;
|
||||
const int precision = MAX(1, total_digits - (int)Math::floor(magnitude));
|
||||
|
||||
r_result += String::num(num, precision);
|
||||
if (p_full_precision) {
|
||||
const String num_sci = String::num_scientific(num);
|
||||
if (num_sci.contains_char('.') || num_sci.contains_char('e')) {
|
||||
r_result += num_sci;
|
||||
} else {
|
||||
r_result += num_sci + ".0";
|
||||
}
|
||||
} else {
|
||||
const double magnitude = std::log10(Math::abs(num));
|
||||
const int precision = MAX(1, 14 - (int)Math::floor(magnitude));
|
||||
r_result += String::num(num, precision);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case Variant::PACKED_INT32_ARRAY:
|
||||
|
||||
@@ -8423,7 +8423,7 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path)
|
||||
constexpr uint32_t text_chunk_type = 0x4E4F534A; // The byte sequence "JSON" as little-endian.
|
||||
constexpr uint32_t binary_chunk_type = 0x004E4942; // The byte sequence "BIN\0" as little-endian.
|
||||
|
||||
String json_string = Variant(p_state->json).to_json_string();
|
||||
String json_string = JSON::stringify(p_state->json, "", true, true);
|
||||
CharString cs = json_string.utf8();
|
||||
uint64_t text_data_length = cs.length();
|
||||
uint64_t text_chunk_length = ((text_data_length + 3) & (~3));
|
||||
@@ -8440,7 +8440,7 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path)
|
||||
err = _encode_buffer_bins(p_state, p_path);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
// Since the buffer bins were re-encoded, we need to re-convert the JSON to string.
|
||||
json_string = Variant(p_state->json).to_json_string();
|
||||
json_string = JSON::stringify(p_state->json, "", true, true);
|
||||
cs = json_string.utf8();
|
||||
text_data_length = cs.length();
|
||||
text_chunk_length = ((text_data_length + 3) & (~3));
|
||||
@@ -8483,7 +8483,7 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> p_state, const String p_path)
|
||||
ERR_FAIL_COND_V(file.is_null(), FAILED);
|
||||
|
||||
file->create(FileAccess::ACCESS_RESOURCES);
|
||||
String json = Variant(p_state->json).to_json_string();
|
||||
String json = JSON::stringify(p_state->json, "", true, true);
|
||||
file->store_string(json);
|
||||
}
|
||||
return err;
|
||||
@@ -8617,7 +8617,7 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Erro
|
||||
*r_err = err;
|
||||
}
|
||||
ERR_FAIL_COND_V(err != OK, PackedByteArray());
|
||||
String json_string = Variant(p_state->json).to_json_string();
|
||||
String json_string = JSON::stringify(p_state->json, "", true, true);
|
||||
|
||||
constexpr uint64_t header_size = 12;
|
||||
constexpr uint64_t chunk_header_size = 8;
|
||||
|
||||
@@ -72,8 +72,8 @@ TEST_CASE("[JSON] Stringify arrays") {
|
||||
CHECK(JSON::stringify(indented_array, "\t") == "[\n\t0,\n\t1,\n\t2,\n\t3,\n\t4,\n\t[\n\t\t0,\n\t\t1,\n\t\t2,\n\t\t3,\n\t\t4\n\t]\n]");
|
||||
|
||||
Array full_precision_array;
|
||||
full_precision_array.push_back(0.123456789012345677);
|
||||
CHECK(JSON::stringify(full_precision_array, "", true, true) == "[0.123456789012345677]");
|
||||
full_precision_array.push_back(0.12345678901234568);
|
||||
CHECK(JSON::stringify(full_precision_array, "", true, true) == "[0.12345678901234568]");
|
||||
|
||||
ERR_PRINT_OFF
|
||||
Array self_array;
|
||||
@@ -110,8 +110,8 @@ TEST_CASE("[JSON] Stringify dictionaries") {
|
||||
CHECK(JSON::stringify(outer) == "{\"inner\":{\"key\":\"value\"}}");
|
||||
|
||||
Dictionary full_precision_dictionary;
|
||||
full_precision_dictionary["key"] = 0.123456789012345677;
|
||||
CHECK(JSON::stringify(full_precision_dictionary, "", true, true) == "{\"key\":0.123456789012345677}");
|
||||
full_precision_dictionary["key"] = 0.12345678901234568;
|
||||
CHECK(JSON::stringify(full_precision_dictionary, "", true, true) == "{\"key\":0.12345678901234568}");
|
||||
|
||||
ERR_PRINT_OFF
|
||||
Dictionary self_dictionary;
|
||||
@@ -352,16 +352,16 @@ TEST_CASE("[JSON] Serialization") {
|
||||
|
||||
static FpTestCase fp_tests_full_precision[] = {
|
||||
{ 0.0, "0.0" },
|
||||
{ 1000.1234567890123456789, "1000.12345678901238" },
|
||||
{ -1000.1234567890123456789, "-1000.12345678901238" },
|
||||
{ DBL_MAX, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0" },
|
||||
{ DBL_MAX - 1, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0" },
|
||||
{ std::pow(2, 53), "9007199254740992.0" },
|
||||
{ -std::pow(2, 53), "-9007199254740992.0" },
|
||||
{ 0.00000000000000011, "0.00000000000000011" },
|
||||
{ -0.00000000000000011, "-0.00000000000000011" },
|
||||
{ 1.0 / 3.0, "0.333333333333333315" },
|
||||
{ 0.9999999999999999, "0.999999999999999889" },
|
||||
{ 1000.1234567890123456789, "1000.1234567890124" },
|
||||
{ -1000.1234567890123456789, "-1000.1234567890124" },
|
||||
{ DBL_MAX, "1.7976931348623157e+308" },
|
||||
{ DBL_MAX - 1, "1.7976931348623157e+308" },
|
||||
{ std::pow(2, 53), "9.007199254740992e+15" },
|
||||
{ -std::pow(2, 53), "-9.007199254740992e+15" },
|
||||
{ 0.00000000000000011, "1.1e-16" },
|
||||
{ -0.00000000000000011, "-1.1e-16" },
|
||||
{ 1.0 / 3.0, "0.3333333333333333" },
|
||||
{ 0.9999999999999999, "0.9999999999999999" },
|
||||
{ 1.0000000000000001, "1.0" },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user