jacobwilliams / json-fortran

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

Error in parsing numbers exceeding the range of a integer. #444

Closed tsbg closed 4 years ago

tsbg commented 4 years ago

Hi

in version 7.1.0, the following JSON: { "x": 2147483648 } results in the error: "Error in string_to_int: string cannot be converted to an integer: 2147483648"

The number 2147483648 exceeds the range of signed 4 Byte integer but it is still a valid JSON Number. I think, when the conversion to integer fails, a conversion to a real value should be attempted.

What do you think?

jacobwilliams commented 4 years ago

We could add it as an option, but it might be tricky. Note that you can compile the library with different real and int kinds. For example, if you can enable single, double, and quad real kinds. Which one would it try first if the int conversion failed? And is the reverse situation ever possible (maybe you build it with single precision reals, but very large ints? Would we try to convert it to an int if the real conversion failed?)

tsbg commented 4 years ago

Let me explain the problem in more detail. I have a GUI running with Javascript in a web browser. This GUI sends its data as JSON to a Fortran CGI program which performs some calculations and returns the result again as JSON to the GUI. If I am satisfied with the result, I can send the results again as JSON to the Fortran CGI, which then saves the data to a file. It is this last step which fails. The Fortran program sends for example the following double precision real value: 3.453592576E+9. Because this value is exactly representable as a Javascript number, the GUI sends back 3453592576 which the Fortran program interprets as an integer and then fails, because the value it is to big for the selected integer kind.

I think a runtime option would be a good solution. In my opinion, the conversion should be done only from integer to real. If multiple real kinds are enabled, the conversion should be done to the smallest real kind which is able to represent the integer without loss of precision.

jacobwilliams commented 4 years ago

Yes, I see. I can add it as an option. It should be fairly straightforward.

tsbg commented 4 years ago

That would be great, thank you very much.

jacobwilliams commented 4 years ago

To enable it, you'll need to use this new argument in the initialize routine:

call json%initialize(strict_integer_type_checking=.false.)

Note that the default is true to maintain backward compatibility with the previous behavior.

I'll merge it in to master soon... I also need to tag a new release.