jacobwilliams / json-fortran

A Modern Fortran JSON API
https://jacobwilliams.github.io/json-fortran/
Other
338 stars 86 forks source link

NaN is serialized to NaN should be "null" #395

Closed Schultzer closed 5 years ago

Schultzer commented 5 years ago

Following the JSON spec NaN and +/- infinity should be serialized to "null"

https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript

Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String null.
jacobwilliams commented 5 years ago

I'm not sure what you are proposing. NaN and +/- Infinity cannot be represented in JSON. The quote above is from the Javascript spec which isn't the same thing.

My preference would be to parse NaN, +Infinity, -Infinity as the corresponding floating point values, perhaps using some trickery with ieee_positive_inf, ieee_negative_inf, and ieee_quiet_nan.

zbeekman commented 5 years ago

An option for signaling NaN would be nice, FWIW.

Schultzer commented 5 years ago

Hi Jacob,

I'm sorry for the confusion.

If I do something like this

type(json_core) :: json
type(json_value), pointer :: root
zero = 0
nan = 0/zero
call json%add(root, 'nan', nan)
call json%print(root, './nan.json')
call json%destroy(root)

I would get {"nan": NaN} instead of {"nan": "null"}

I guess what I'm proposing is to serialize NaN and Infinity into "null" in the output.

Let me know if this cleared things up a bit.

jacobwilliams commented 5 years ago

I guess we could have different options. Keep in mind that it also has to work for parsing. Would it be better to represent it as the JSON null value rather than a string? The options could be:

The problem with the first two is that they aren't reversible. You can add a +Infinity but you can't get it back. The last one is reversable. This could be important if using an array. For example: it seems weird to produce something like this: "x": [1.0, "null", 2.0, 3.0, "null"] from a vector of reals. Maybe 4th slightly better option would be:

Schultzer commented 5 years ago

I feel this is inherently difficult, given the JSON spec, in a perfect world JSON would adhere to ieee floating points, it bit me in the foot, when I found out that JSON did not support ieee.

I'm using your lib in my blas project, but given all these issues, I might just do the serializing from fortran to rust myself, then using JSON as format in between.

I like your idea to have an optional JSON5 parser, but maybe even just documenting that we don't follow spec when it comes to NaN and Infinities is sufficient.

jacobwilliams commented 5 years ago

Note: see the new initialize() options: null_to_real_mode, non_normal_mode, and use_quiet_nan. They will be in the next release.