Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle infinity and NaN cases #70

Closed
EricMCornelius opened this issue May 5, 2015 · 4 comments
Closed

Handle infinity and NaN cases #70

EricMCornelius opened this issue May 5, 2015 · 4 comments
Assignees

Comments

@EricMCornelius
Copy link

http://en.cppreference.com/w/cpp/io/c/fprintf

snprintf will format infinity and nan doubles as Inf/Infinity or nan/nan(char_sequence) respectively. This can break the validity of a json.dump() document:

json/src/json.hpp

Line 2279 in 1580eee

const auto sz = static_cast<unsigned int>(std::snprintf(nullptr, 0, "%.15g", m_value.number_float));

You can check for infinity/nan w/ std::isinfinite/std::isnan - not sure what you'd like to actually do in those scenarios (some specific/configurable string representation?)

http://en.cppreference.com/w/cpp/numeric/math/isfinite

@EricMCornelius
Copy link
Author

Looking into what others do, it seems the ECMAScript 5.1 specification explicitly specifies stringifying +/- Infinity and NaN as null.

NOTE 4 Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String null.

http://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3

Of course, 'the String null' is pleasantly ambiguous. In Chrome I see it's actually doing:

JSON.stringify({x: NaN});
"{"x":null}"

@nlohmann
Copy link
Owner

nlohmann commented May 6, 2015

Hi @EricMCornelius, thanks for the note. I'll check it tonight. All the best, Niels

@nlohmann nlohmann self-assigned this May 6, 2015
@nlohmann
Copy link
Owner

With 3.0.0, the semantics of this changed: NAN and infinity are stored properly inside the JSON value (no exception or conversion to null), but are serialized as null.

(#329 and #388 are related).

nlohmann added a commit that referenced this issue Mar 12, 2017
- If an overflow occurs during parsing a number from a JSON text, an
exception (std::out_of_range for the moment, to be replaced by a
user-defined exception #244) is thrown so that the overflow is detected
early and roundtripping is guaranteed.
- NaN and INF floating-point values can be stored in a JSON value and
are not replaced by null. That is, the basic_json class behaves like
double in this regard (no exception occurs). However, NaN and INF are
serialized to “null”.
- Adjusted test cases appropriately.
@nlohmann
Copy link
Owner

This issue is fixed with 8feaf8d as follows:

  • If an overflow occurs during parsing a number from a JSON text, an exception (std::out_of_range for the moment, to be replaced by a user-defined exception Use user-defined exceptions #244) is thrown so that the overflow is detected early and roundtripping is guaranteed.
  • NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like double in this regard (no exception occurs). However, NaN and INF are serialized to “null”.
  • Adjusted test cases appropriately.

Waiting for Travis to complete. Then this issue can be closed and the different semantics can be described in the wiki.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants