diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0171a244b..ea57e6505 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,5 @@ +[![Issue Stats](http://issuestats.com/github/nlohmann/json/badge/pr?style=flat)](http://issuestats.com/github/nlohmann/json) [![Issue Stats](http://issuestats.com/github/nlohmann/json/badge/issue?style=flat)](http://issuestats.com/github/nlohmann/json) + # How to contribute This project started as a little excuse to exercise some of the cool new C++11 features. Over time, people actually started to use the JSON library (yey!) and started to help improve it by proposing features, finding bugs, or even fixing my mistakes. I am really [thankful](https://github.com/nlohmann/json/blob/master/README.md#thanks) for this and try to keep track of all the helpers. @@ -72,4 +74,5 @@ The following areas really need contribution: - Extending the **continuous integration** beyond Linux running some versions of GCC and Clang on [Travis](https://travis-ci.org/nlohmann/json) and Microsoft Visual Studio on [AppVeyor](https://ci.appveyor.com/project/nlohmann/json). We have found a lot of bugs just because several compilers behave in a slightly different manner. - Improving the efficiency of the **JSON parser**. The current parser is implemented as a naive recursive descent parser with hand coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the `json.hpp` header, and I am not aware of approaches similar to [`re2c`](http://re2c.org) for parsing. - Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting. -- Check the code with [Coverity](https://scan.coverity.com). +- Check the code with [**Coverity**](https://scan.coverity.com). +- Make the code **locale-independent**. The library currently only works for a locale where `.` is the decimal point character. diff --git a/README.md b/README.md index 6d45c2a21..93b4395ac 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ Other aspects were not so important to us: - **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) with a decent regular expression processor should be even faster (but would consist of more files which makes the integration harder). +See the [https://github.com/nlohmann/json/blob/master/CONTRIBUTING.md#please-dont](contribution guidelines) for more information. + ## Integration The single required source, file `json.hpp` is in the `src` directory or [released here](https://github.com/nlohmann/json/releases). All you need to do is add diff --git a/src/json.hpp b/src/json.hpp index 0c3f6aac8..f536c513c 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -5873,10 +5873,16 @@ class basic_json case value_t::number_float: { - // 15 digits of precision allows round-trip IEEE 754 - // 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; + // 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 + o << std::setprecision(std::numeric_limits::digits10); + } + o << m_value.number_float; return; } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 4a796dbb0..c59fdc6b7 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -5873,10 +5873,16 @@ class basic_json case value_t::number_float: { - // 15 digits of precision allows round-trip IEEE 754 - // 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; + // 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 + o << std::setprecision(std::numeric_limits::digits10); + } + o << m_value.number_float; return; } diff --git a/test/unit.cpp b/test/unit.cpp index 233fe1f6c..eb4061603 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -11751,15 +11751,15 @@ 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/roundtrip20.json", - //"test/json_roundtrip/roundtrip21.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", "test/json_roundtrip/roundtrip23.json", //"test/json_roundtrip/roundtrip24.json", @@ -12263,6 +12263,8 @@ TEST_CASE("regression tests") j = json::parse("0.999999999999999944488848768742172978818416595458984374"); CHECK(j.get() == 0.99999999999999989); + // Test fails under GCC/clang due to strtod() error (may originate in libstdc++ + // but seems to have been fixed in the most current versions - just not on Travis) #if !defined(__clang__) && !defined(__GNUC__) && !defined(__GNUG__) j = json::parse("1.00000000000000011102230246251565404236316680908203126"); CHECK(j.get() == 1.00000000000000022);