Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions core/io/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 4 additions & 4 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 14 additions & 14 deletions tests/core/io/test_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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" },
};

Expand Down
Loading