diff --git a/src/json.hpp b/src/json.hpp index aea4a5eb..eb95cb9f 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2283,8 +2283,9 @@ class basic_json case (value_t::number_float): { // 15 digits of precision allows round-trip IEEE 754 - // string->double->string - o << std::setprecision(15) << m_value.number_float; + // string->double->string; to be safe, we read this value from + // std::numeric_limits::digits10 + o << std::setprecision(std::numeric_limits::digits10) << m_value.number_float; return; } @@ -4547,12 +4548,12 @@ basic_json_parser_59: @exception std::range_error if passed value is out of range */ - number_float_t get_number() const + long double get_number() const { // conversion typename string_t::value_type* endptr; - const auto float_val = std::strtod(reinterpret_cast(m_start), - &endptr); + const auto float_val = std::strtold(reinterpret_cast(m_start), + &endptr); // return float_val if the whole number was translated and NAN // otherwise @@ -4787,7 +4788,7 @@ basic_json_parser_59: // check if conversion loses precision const auto int_val = static_cast(float_val); - if (approx(float_val, static_cast(int_val))) + if (approx(float_val, static_cast(int_val))) { // we basic_json not lose precision -> return int result.m_type = value_t::number_integer; @@ -4797,7 +4798,7 @@ basic_json_parser_59: { // we would lose precision -> returnfloat result.m_type = value_t::number_float; - result.m_value = float_val; + result.m_value = static_cast(float_val); } break; } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 1169e6d9..3c982903 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2283,8 +2283,9 @@ class basic_json case (value_t::number_float): { // 15 digits of precision allows round-trip IEEE 754 - // string->double->string - o << std::setprecision(15) << m_value.number_float; + // string->double->string; to be safe, we read this value from + // std::numeric_limits::digits10 + o << std::setprecision(std::numeric_limits::digits10) << m_value.number_float; return; } @@ -3853,12 +3854,12 @@ class basic_json @exception std::range_error if passed value is out of range */ - number_float_t get_number() const + long double get_number() const { // conversion typename string_t::value_type* endptr; - const auto float_val = std::strtod(reinterpret_cast(m_start), - &endptr); + const auto float_val = std::strtold(reinterpret_cast(m_start), + &endptr); // return float_val if the whole number was translated and NAN // otherwise @@ -4093,7 +4094,7 @@ class basic_json // check if conversion loses precision const auto int_val = static_cast(float_val); - if (approx(float_val, static_cast(int_val))) + if (approx(float_val, static_cast(int_val))) { // we basic_json not lose precision -> return int result.m_type = value_t::number_integer; @@ -4103,7 +4104,7 @@ class basic_json { // we would lose precision -> returnfloat result.m_type = value_t::number_float; - result.m_value = float_val; + result.m_value = static_cast(float_val); } break; } diff --git a/test/unit.cpp b/test/unit.cpp index ec0f9f27..29b9e7a2 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -8688,13 +8688,13 @@ TEST_CASE("compliance tests from nativejson-benchmark") "test/json_roundtrip/roundtrip10.json", "test/json_roundtrip/roundtrip11.json", "test/json_roundtrip/roundtrip12.json", - //"test/json_roundtrip/roundtrip13.json", + "test/json_roundtrip/roundtrip13.json", "test/json_roundtrip/roundtrip14.json", "test/json_roundtrip/roundtrip15.json", "test/json_roundtrip/roundtrip16.json", "test/json_roundtrip/roundtrip17.json", - //"test/json_roundtrip/roundtrip18.json", - //"test/json_roundtrip/roundtrip19.json", + "test/json_roundtrip/roundtrip18.json", + "test/json_roundtrip/roundtrip19.json", //"test/json_roundtrip/roundtrip20.json", //"test/json_roundtrip/roundtrip21.json", "test/json_roundtrip/roundtrip22.json", @@ -8708,7 +8708,7 @@ TEST_CASE("compliance tests from nativejson-benchmark") CAPTURE(filename); std::ifstream f(filename); std::string json_string( (std::istreambuf_iterator(f) ), - (std::istreambuf_iterator() ) ); + (std::istreambuf_iterator()) ); json j = json::parse(json_string); CHECK(j.dump() == json_string);