diff --git a/README.md b/README.md index 93b4395a..44c17bf0 100644 --- a/README.md +++ b/README.md @@ -390,7 +390,7 @@ I deeply appreciate the help of the following people. - [406345](https://github.com/406345) fixed two small warnings. - [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. - [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. -- [twelsby](https://github.com/twelsby) fixed the array subscript operator and an issue that failed the MSVC build. +- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. Thanks a lot for helping out! @@ -407,7 +407,7 @@ $ make $ ./json_unit "*" =============================================================================== -All tests passed (3343318 assertions in 29 test cases) +All tests passed (3343329 assertions in 29 test cases) ``` For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). diff --git a/src/json.hpp b/src/json.hpp index f536c513..90941b71 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -5873,13 +5873,20 @@ class basic_json case value_t::number_float: { - // If the number is an integer then output as a fixed with with precision 1 - // to output "0.0", "1.0" etc as expected for some round trip tests otherwise - // 15 digits of precision allows round-trip IEEE 754 string->double->string; - // to be safe, we read this value from std::numeric_limits::digits10 - if (std::fmod(m_value.number_float, 1) == 0) o << std::fixed << std::setprecision(1); - else { - o.unsetf(std::ios_base::floatfield); // std::defaultfloat not supported in gcc version < 5 + // If the number is an integer then output as a fixed with with + // precision 1 to output "0.0", "1.0" etc as expected for some + // round trip tests otherwise 15 digits of precision allows + // round-trip IEEE 754 string->double->string; to be safe, we + // read this value from + // std::numeric_limits::digits10 + if (std::fmod(m_value.number_float, 1) == 0) + { + o << std::fixed << std::setprecision(1); + } + else + { + // std::defaultfloat not supported in gcc version < 5 + o.unsetf(std::ios_base::floatfield); o << std::setprecision(std::numeric_limits::digits10); } o << m_value.number_float; @@ -7637,11 +7644,17 @@ basic_json_parser_64: supplied via the first parameter. Set this to @a static_cast(nullptr). - @param type the @ref number_float_t in use + @param[in] type the @ref number_float_t in use - @param endptr recieves a pointer to the first character after the number + @param[in,out] endptr recieves a pointer to the first character after + the number @return the floating point number + + @warning This function uses `std::strtof`, `std::strtod`, or + `std::strtold` which use the current C locale to determine which + character is used as decimal point character. This may yield to parse + errors if the locale does not used `.`. */ long double str_to_float_t(long double* /* type */, char** endptr) const { diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index c59fdc6b..4939f194 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -5873,13 +5873,20 @@ class basic_json case value_t::number_float: { - // If the number is an integer then output as a fixed with with precision 1 - // to output "0.0", "1.0" etc as expected for some round trip tests otherwise - // 15 digits of precision allows round-trip IEEE 754 string->double->string; - // to be safe, we read this value from std::numeric_limits::digits10 - if (std::fmod(m_value.number_float, 1) == 0) o << std::fixed << std::setprecision(1); - else { - o.unsetf(std::ios_base::floatfield); // std::defaultfloat not supported in gcc version < 5 + // If the number is an integer then output as a fixed with with + // precision 1 to output "0.0", "1.0" etc as expected for some + // round trip tests otherwise 15 digits of precision allows + // round-trip IEEE 754 string->double->string; to be safe, we + // read this value from + // std::numeric_limits::digits10 + if (std::fmod(m_value.number_float, 1) == 0) + { + o << std::fixed << std::setprecision(1); + } + else + { + // std::defaultfloat not supported in gcc version < 5 + o.unsetf(std::ios_base::floatfield); o << std::setprecision(std::numeric_limits::digits10); } o << m_value.number_float; @@ -7319,11 +7326,17 @@ class basic_json supplied via the first parameter. Set this to @a static_cast(nullptr). - @param type the @ref number_float_t in use + @param[in] type the @ref number_float_t in use - @param endptr recieves a pointer to the first character after the number + @param[in,out] endptr recieves a pointer to the first character after + the number @return the floating point number + + @warning This function uses `std::strtof`, `std::strtod`, or + `std::strtold` which use the current C locale to determine which + character is used as decimal point character. This may yield to parse + errors if the locale does not used `.`. */ long double str_to_float_t(long double* /* type */, char** endptr) const {