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

[Question] Floating point resolution config during dump() ? #768

Closed
rstoica opened this issue Oct 6, 2017 · 10 comments
Closed

[Question] Floating point resolution config during dump() ? #768

rstoica opened this issue Oct 6, 2017 · 10 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated

Comments

@rstoica
Copy link

rstoica commented Oct 6, 2017

Hello,

First of all I would like to thank for doing such a nice job in developing and maintaining a top-notch C++ JSON code base!

I am a new user of this library, so maybe my question may be well documented somewhere, but I might have overlooked the explanation (if this is the case apologies beforehand but please point it out to me).

Is there any functionality exposed to limit the floating point resolution during dump() ?

Context: I am asking this as I am not using the basic output streams or its derivatives but an MQTT publisher. So basically I just dump the JSON objects that I have to the MQTT interface as a string. As of now, the float data fields have by default 10 or so decimal places as explained in the documentation, but is there a flag / API to restrict that to a configurable number, e.g. 2 decimals only ?

Best,
Andrei

@nlohmann
Copy link
Owner

nlohmann commented Oct 6, 2017

The precision is set in https://github.com/nlohmann/json/blob/develop/src/json.hpp#L6701 and uses std::numeric_limits<number_float_t>::digits10 digits at the moment. This value is sufficient to guarantee roundtripping and is not exposed in the API. If you only require two digits, this is the place to change the code.

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Oct 6, 2017
@rstoica
Copy link
Author

rstoica commented Oct 6, 2017

Thanks a lot for the quick reply and proposed fix!

I understand the strong requirements behind round trip conversions especially for floating point values. As a follow up, do you believe it would bring some added value to the API to have a specialized dump() interface for the case I have outlined above ?

@nlohmann
Copy link
Owner

nlohmann commented Oct 7, 2017

With the current interface of dump it would be rather ugly, and the use case is not so broad that it would be worth going that way. However, if we would find a nicer way to control the settings of the dump function, this could be added.

@stale
Copy link

stale bot commented Nov 6, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Nov 6, 2017
@stale stale bot closed this as completed Nov 13, 2017
@eike-fokken
Copy link

eike-fokken commented Nov 2, 2021

Hi there!
What is currently a possibility to hardcode a different precision? I tried fiddling with some lines containing

std::numeric_limits<FloatType>::digits10

and

std::numeric_limits<number_float_t>::max_digits10

but that didn't change the output of dump(). Would you have a hint for me?

@nlohmann
Copy link
Owner

nlohmann commented Nov 3, 2021

This is not possible any longer as the library is using the Grisu2 algorithm rather than printf for the float-to-string conversion, see include/nlohmann/detail/conversions/to_chars.hpp.

@eike-fokken
Copy link

eike-fokken commented Nov 3, 2021

That's sad for me.
I use json as output format of numerical computations and it would be easier to quickly find regressions if I could tune down the precision such that different compiler optimizations don't change the result.
Looks like I have to write a compare_json_output_up_to_precision function. A pity.
Out of curiosity: Do you see a tuning parameter for dump() in the foreseeable future?
I guess I would have to understand the grisu2 algorithm to contribute one but from your posts here and there you probably have more thoughts on if and how to implement such a parameter, right?

@nlohmann
Copy link
Owner

nlohmann commented Nov 3, 2021

  1. I don't really understand why would would like to change the precision of the output.
  2. I would not say it's impossible to change the precision of the Grisu2 algorithm - I'm not expert in it though.
  3. There are frequent questions for an extension of dump - the problem right now is to find an API that allows to tweak all interesting aspects and still allows to be changed later one. That said, adding more parameters to the function is clearly not a good idea. Maybe a struct encapsulating all parameters? But then adding a new parameter would be a breaking change?

@eike-fokken
Copy link

eike-fokken commented Nov 3, 2021

  1. I don't really understand why would would like to change the precision of the output.

Well as stated above: The full precision also reflects very small changes in floats, that in my usecase are irrelevant. In my case they come from different optimization paths of different compilers or even the same compiler on slightly different source code (that mathematically would lead to the same results but doesn't on floating point numbers).

Tuning down the precision means that I could actually diff the results of two versions and would get no changes, if my code was correct.

Now I have to read the result jsons in a compare-function that declares numbers that differ only up to 10^(-12) to be equivalent or have to make sure that my program only saves rounded numbers into the json. Both possible but much less convenient for me compared to someone having done the hardwork here, that's why I asked.

  1. There are frequent questions for an extension of dump - the problem right now is to find an API that allows to tweak all interesting aspects and still allows to be changed later one. That said, adding more parameters to the function is clearly not a good idea. Maybe a struct encapsulating all parameters? But then adding a new parameter would be a breaking change?

If its possible to group all parameters into a common class, they could be in a container and have an id (an int?), such that older versions of dump can deny using parameters that are too new for them.
But I'm rather new to C++, and this is only the first idea I have on this, so probably not a good one.

@desultroy
Copy link

  1. I don't really understand why would would like to change the precision of the output.

Since I am not really finding a solution that I am happy with, I want to give my reason why I want to change the resolution of the output string.

My Application has a websocket connection to a website used as a GUI. I want to display the values of the application with 3 decimal places to the user. I don't see the point of sending a string with the full precision and have the browser do the shorting. I don't like to make a second copy in my application with a shortend double of every value I want to display.

for now I will do something like this:

double round2(double value, double multiplier)
{
  return round(value * multiplier) / multiplier;
}

...
jsonOut["test"] =round2(testdouble, 1000);

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 state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated
Projects
None yet
Development

No branches or pull requests

4 participants