fixed more float parsing cases

This commit is contained in:
Niels 2015-06-13 12:42:18 +02:00
parent 7c579f11e5
commit bd0cb65b7a
3 changed files with 20 additions and 18 deletions

View file

@ -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,11 +4548,11 @@ 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
@ -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;
} }

View file

@ -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,11 +3854,11 @@ 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
@ -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;
} }

View file

@ -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);