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

Double type converts to scientific notation #1661

Closed
chriseyhorn opened this issue Jul 2, 2019 · 10 comments
Closed

Double type converts to scientific notation #1661

chriseyhorn opened this issue Jul 2, 2019 · 10 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@chriseyhorn
Copy link

Sample:
nlohmann::json message;
message["id"] = 1431756631463478;
std::cout << message.dump();

Actual: { "id" : 1.431756631463478e+15 }
Expected: { "id" : 1431756631463478 }

Is there a setting for turning off scientific notation conversion?

@nlohmann
Copy link
Owner

nlohmann commented Jul 3, 2019

I cannot reproduce the issue - the output is

{"id":1431756631463478}

on my machine. My guess would be that you're running a 32 bit system where the given number does not fit to an integer and is store as float internally. We use the Grisu2 algorithm to produce a string representation of floating-point numbers. I am afraid there is no configuration not to use scientific notation here.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Jul 11, 2019
@ChoppinBlockParty
Copy link

I run on 64-bit linux but get doubles converted to scientific. I know that rapidjson is using Grisu2 as well, but it does not convert to scientific.

@nlohmann
Copy link
Owner

I run on 64-bit linux but get doubles converted to scientific. I know that rapidjson is using Grisu2 as well, but it does not convert to scientific.

Do you have a working example?

@ChoppinBlockParty
Copy link

0.00004941 would be dump as 4.941e-05 with the library, rapidjson would print it in a fixed notation. I know that scientific notation does saves bytes. However, I think it depends on the use-case, if you do json printing to humans you'd like to have fixed notation and better in general for debugging purposes for people who do not care about extra bytes. Would be a nice option to have.

@nlohmann
Copy link
Owner

This is not about saving space.

double d = 0.00004941;
std::cout << d << std::endl;

The output is also 4.941e-05.

It is about being able to round-trip values. The double 0.00004941 is best approximated with 0x3f09e7b2ac3a3028:

std::printf("%A\n", d);

The output is 0x1.9e7b2ac3a3028p-15.

You get the same output after roundtripping:

json j = json::parse("0.00004941");
std::printf("%a\n", j.get<double>());	

There is currently no way to change this behavior. However, adding more decimal places does not make the output more precise.

@ChoppinBlockParty
Copy link

I agree. But what I am saying is not about std::printf (though being C/C++ famous way of printing numbers, not an ultimate remedy) round-tripping, I am trying to be more generic in the sense as JSON format is not C++-specific (rather js-specific). C++/C inherently lacks human-friendly float-to-decimal conversions (like with Gsus2, or netlib dtoa, etc.) that are included in languages like Pythong, or javascript. Thus to be more cross-language compatible I think you should have something like this in the library.

@nlohmann
Copy link
Owner

Can you elaborate on the "human-friendly" aspect of these libraries?

@ChoppinBlockParty
Copy link

Can you elaborate on the "human-friendly" aspect of these libraries?

Assume you have a command-line tool that converts something to JSON format. You can grep (or use any other favourite text processing tool) stuff there. If your doubles are in a scientific notation it is hard to grep it.

That was very simple one case, that is very popular where I am working. Another one can be the popular JSON web endpoints where one might desire investigating output. I quite sure you can find many more cases where human-readability of the raw format output is helpful.

Just for the contrast, if you are an exchange and have REST endpoints, you probably, will choose the output to be as short as possible, rather then its readability.

Does it make any sense?

@gregmarr
Copy link
Contributor

FYI, I personally don't find scientific notation any less readable, and often find it more readable for large/small numbers.

@ChoppinBlockParty
Copy link

@gregmarr Yeah, that is why I kind of think if there was a setting where you can control it, that would be nice for different use-cases.

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

4 participants