fixed more float parsing cases
This commit is contained in:
parent
7c579f11e5
commit
bd0cb65b7a
3 changed files with 20 additions and 18 deletions
15
src/json.hpp
15
src/json.hpp
|
@ -2283,8 +2283,9 @@ class basic_json
|
||||||
case (value_t::number_float):
|
case (value_t::number_float):
|
||||||
{
|
{
|
||||||
// 15 digits of precision allows round-trip IEEE 754
|
// 15 digits of precision allows round-trip IEEE 754
|
||||||
// string->double->string
|
// string->double->string; to be safe, we read this value from
|
||||||
o << std::setprecision(15) << m_value.number_float;
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4547,12 +4548,12 @@ basic_json_parser_59:
|
||||||
|
|
||||||
@exception std::range_error if passed value is out of range
|
@exception std::range_error if passed value is out of range
|
||||||
*/
|
*/
|
||||||
number_float_t get_number() const
|
long double get_number() const
|
||||||
{
|
{
|
||||||
// conversion
|
// conversion
|
||||||
typename string_t::value_type* endptr;
|
typename string_t::value_type* endptr;
|
||||||
const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
|
const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
|
||||||
&endptr);
|
&endptr);
|
||||||
|
|
||||||
// return float_val if the whole number was translated and NAN
|
// return float_val if the whole number was translated and NAN
|
||||||
// otherwise
|
// otherwise
|
||||||
|
@ -4787,7 +4788,7 @@ basic_json_parser_59:
|
||||||
|
|
||||||
// check if conversion loses precision
|
// check if conversion loses precision
|
||||||
const auto int_val = static_cast<number_integer_t>(float_val);
|
const auto int_val = static_cast<number_integer_t>(float_val);
|
||||||
if (approx(float_val, static_cast<number_float_t>(int_val)))
|
if (approx(float_val, static_cast<long double>(int_val)))
|
||||||
{
|
{
|
||||||
// we basic_json not lose precision -> return int
|
// we basic_json not lose precision -> return int
|
||||||
result.m_type = value_t::number_integer;
|
result.m_type = value_t::number_integer;
|
||||||
|
@ -4797,7 +4798,7 @@ basic_json_parser_59:
|
||||||
{
|
{
|
||||||
// we would lose precision -> returnfloat
|
// we would lose precision -> returnfloat
|
||||||
result.m_type = value_t::number_float;
|
result.m_type = value_t::number_float;
|
||||||
result.m_value = float_val;
|
result.m_value = static_cast<number_float_t>(float_val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2283,8 +2283,9 @@ class basic_json
|
||||||
case (value_t::number_float):
|
case (value_t::number_float):
|
||||||
{
|
{
|
||||||
// 15 digits of precision allows round-trip IEEE 754
|
// 15 digits of precision allows round-trip IEEE 754
|
||||||
// string->double->string
|
// string->double->string; to be safe, we read this value from
|
||||||
o << std::setprecision(15) << m_value.number_float;
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3853,12 +3854,12 @@ class basic_json
|
||||||
|
|
||||||
@exception std::range_error if passed value is out of range
|
@exception std::range_error if passed value is out of range
|
||||||
*/
|
*/
|
||||||
number_float_t get_number() const
|
long double get_number() const
|
||||||
{
|
{
|
||||||
// conversion
|
// conversion
|
||||||
typename string_t::value_type* endptr;
|
typename string_t::value_type* endptr;
|
||||||
const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
|
const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
|
||||||
&endptr);
|
&endptr);
|
||||||
|
|
||||||
// return float_val if the whole number was translated and NAN
|
// return float_val if the whole number was translated and NAN
|
||||||
// otherwise
|
// otherwise
|
||||||
|
@ -4093,7 +4094,7 @@ class basic_json
|
||||||
|
|
||||||
// check if conversion loses precision
|
// check if conversion loses precision
|
||||||
const auto int_val = static_cast<number_integer_t>(float_val);
|
const auto int_val = static_cast<number_integer_t>(float_val);
|
||||||
if (approx(float_val, static_cast<number_float_t>(int_val)))
|
if (approx(float_val, static_cast<long double>(int_val)))
|
||||||
{
|
{
|
||||||
// we basic_json not lose precision -> return int
|
// we basic_json not lose precision -> return int
|
||||||
result.m_type = value_t::number_integer;
|
result.m_type = value_t::number_integer;
|
||||||
|
@ -4103,7 +4104,7 @@ class basic_json
|
||||||
{
|
{
|
||||||
// we would lose precision -> returnfloat
|
// we would lose precision -> returnfloat
|
||||||
result.m_type = value_t::number_float;
|
result.m_type = value_t::number_float;
|
||||||
result.m_value = float_val;
|
result.m_value = static_cast<number_float_t>(float_val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8688,13 +8688,13 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
||||||
"test/json_roundtrip/roundtrip10.json",
|
"test/json_roundtrip/roundtrip10.json",
|
||||||
"test/json_roundtrip/roundtrip11.json",
|
"test/json_roundtrip/roundtrip11.json",
|
||||||
"test/json_roundtrip/roundtrip12.json",
|
"test/json_roundtrip/roundtrip12.json",
|
||||||
//"test/json_roundtrip/roundtrip13.json",
|
"test/json_roundtrip/roundtrip13.json",
|
||||||
"test/json_roundtrip/roundtrip14.json",
|
"test/json_roundtrip/roundtrip14.json",
|
||||||
"test/json_roundtrip/roundtrip15.json",
|
"test/json_roundtrip/roundtrip15.json",
|
||||||
"test/json_roundtrip/roundtrip16.json",
|
"test/json_roundtrip/roundtrip16.json",
|
||||||
"test/json_roundtrip/roundtrip17.json",
|
"test/json_roundtrip/roundtrip17.json",
|
||||||
//"test/json_roundtrip/roundtrip18.json",
|
"test/json_roundtrip/roundtrip18.json",
|
||||||
//"test/json_roundtrip/roundtrip19.json",
|
"test/json_roundtrip/roundtrip19.json",
|
||||||
//"test/json_roundtrip/roundtrip20.json",
|
//"test/json_roundtrip/roundtrip20.json",
|
||||||
//"test/json_roundtrip/roundtrip21.json",
|
//"test/json_roundtrip/roundtrip21.json",
|
||||||
"test/json_roundtrip/roundtrip22.json",
|
"test/json_roundtrip/roundtrip22.json",
|
||||||
|
@ -8708,7 +8708,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
|
||||||
CAPTURE(filename);
|
CAPTURE(filename);
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
std::string json_string( (std::istreambuf_iterator<char>(f) ),
|
std::string json_string( (std::istreambuf_iterator<char>(f) ),
|
||||||
(std::istreambuf_iterator<char>() ) );
|
(std::istreambuf_iterator<char>()) );
|
||||||
|
|
||||||
json j = json::parse(json_string);
|
json j = json::parse(json_string);
|
||||||
CHECK(j.dump() == json_string);
|
CHECK(j.dump() == json_string);
|
||||||
|
|
Loading…
Reference in a new issue