diff --git a/src/json.hpp b/src/json.hpp index 6be6a6d9e..4aedb967f 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8310,16 +8310,7 @@ class basic_json static_assert(d == 6 or d == 15 or d == 16 or d == 17, "unexpected NumberType"); - static constexpr auto fmt = d == 6 ? "%.7g" - : d == 15 ? "%.16g" - : d == 16 ? "%.17g" - : d == 17 ? "%.18g" - : "%.19g"; - // I'm not sure why we need to +1 the precision, - // but without it there's a unit-test that fails - // that asserts precision of the output - - snprintf(m_buf.data(), m_buf.size(), fmt, x); + snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x); // read information from locale const auto loc = localeconv(); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 826731714..0ceb4793c 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8310,16 +8310,7 @@ class basic_json static_assert(d == 6 or d == 15 or d == 16 or d == 17, "unexpected NumberType"); - static constexpr auto fmt = d == 6 ? "%.7g" - : d == 15 ? "%.16g" - : d == 16 ? "%.17g" - : d == 17 ? "%.18g" - : "%.19g"; - // I'm not sure why we need to +1 the precision, - // but without it there's a unit-test that fails - // that asserts precision of the output - - snprintf(m_buf.data(), m_buf.size(), fmt, x); + snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x); // read information from locale const auto loc = localeconv(); diff --git a/test/src/unit-inspection.cpp b/test/src/unit-inspection.cpp index 2e3d075df..d5a97b7e9 100644 --- a/test/src/unit-inspection.cpp +++ b/test/src/unit-inspection.cpp @@ -250,17 +250,31 @@ TEST_CASE("object inspection") ss.str(std::string()); // use stringstream for JSON serialization - json j_number = 3.141592653589793; + json j_number = 3.14159265358979; ss << j_number; // check that precision has been overridden during serialization - CHECK(ss.str() == "3.141592653589793"); + CHECK(ss.str() == "3.14159265358979"); // check that precision has been restored CHECK(ss.precision() == 3); } } + SECTION("round trips") + { + for (const auto& s : + {"3.141592653589793", "1000000000000000010E5" + }) + { + json j1 = json::parse(s); + std::string s1 = j1.dump(); + json j2 = json::parse(s1); + std::string s2 = j2.dump(); + CHECK(s1 == s2); + } + } + SECTION("return the type of the object (explicit)") { SECTION("null") diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 8c9c8b927..e476d9334 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -783,4 +783,13 @@ TEST_CASE("regression tests") json j = R"({"bool_value":true,"double_value":2.0,"int_value":10,"level1":{"list_value":[3,"hi",false],"tmp":5.0},"string_value":"hello"})"_json; CHECK(j["double_value"].is_number_float()); } + + SECTION("issue #465 - roundtrip error while parsing 1000000000000000010E5") + { + json j1 = json::parse("1000000000000000010E5"); + std::string s1 = j1.dump(); + json j2 = json::parse(s1); + std::string s2 = j2.dump(); + CHECK(s1 == s2); + } }