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

Intruisive scientific notation when using .dump(); #1698

Closed
Milerius opened this issue Aug 3, 2019 · 6 comments
Closed

Intruisive scientific notation when using .dump(); #1698

Milerius opened this issue Aug 3, 2019 · 6 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@Milerius
Copy link

Milerius commented Aug 3, 2019

  • Describe what you want to achieve.

Hello i'm receiving this current json:

{"price":0.0000972439793401814}

I'm writting a financial software and i want to get this price as a string:

"0.0000972439793401814"

  • Describe what you tried.

Unfortunately when i use json::parse and auto price_as_str = my_json["price"].dump()

i got a weird scientific value: "9.722107501034067e-05" <- I lost my precision here also 9722 vs 9724

It's very annoying because my software cannot using floating point numbers, only string and big integer so i feel it's very intruisive from the original json that return me the full value without scientific notation

Even if the answer from the original api is probably strange according to:

This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available.

  • Describe which system (OS, compiler) you are using.

OSX clang-8

  • Describe which version of the library you are using (release version, develop branch).
    v3.6.1
@nlohmann
Copy link
Owner

nlohmann commented Aug 3, 2019

For the library, "0.0000972439793401814" and "9.72439793401814e-05" are parsed to the same number, represented as 0x3f197deed8101dc5 internally, see https://float.exposed/0x3f197deed8101dc5.

#include "json.hpp"
#include <iostream>
#include <iomanip>

using json = nlohmann::json;

int main()
{
    json j = "0.0000972439793401814"_json;
    json k = "9.72439793401814e-05"_json;
    
    double jd = j.get<double>();
    double kd = k.get<double>();
    
    std::cout << std::boolalpha << (j == k) << std::endl;
}

If you care about how the number is represented as string, then the library's behavior is to allow roundtripping where possible. There is no way to influence the format currently. You are, however, free to convert the value to a double (see above) and print it as you like (i.e., using std::fixed).

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Aug 3, 2019
@Milerius
Copy link
Author

Milerius commented Aug 4, 2019

@nlohmann I am not really convinced of this answer. I do not want to treat the result of the json as a double, but rather like a string, just retrieve this field as a string without any value changes made by the library. Basically enjoy the parser to access only the fields but as a string. (the main reason is that I can have as a response double containing commercial rounding errors) and I sometimes have to exceed the number of decimal places that a duplicate can handle

@nlohmann
Copy link
Owner

nlohmann commented Aug 4, 2019

The library has no way of accessing the originally parsed string later. During parsing, however, it is available in the SAX interface: https://nlohmann.github.io/json/structnlohmann_1_1json__sax_ae7c31614e8a82164d2d7f8dbf4671b25.html#ae7c31614e8a82164d2d7f8dbf4671b25

Here is a description of how to use it in a similar setting: #1627 (comment)

@Milerius
Copy link
Author

Milerius commented Aug 4, 2019

is this possible to have the key during the sax parsing (like current key) ? @nlohmann

otherwise it's seem's to work i just tested it, but if i can have the name of the key it's great too

I have the garantee that each time the key() function from sax will be called before number_float()

so i can assume that when i'm in number_float() the current_key is what i got in the last call of key ?

@nlohmann
Copy link
Owner

nlohmann commented Aug 4, 2019

@Milerius
Copy link
Author

Milerius commented Aug 4, 2019

Thank's for your help !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

2 participants