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

Is there a way to control the precision of serialized floating point numbers? #677

Closed
gonzalobenegas opened this issue Aug 4, 2017 · 13 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@gonzalobenegas
Copy link

I currently see doubles are being serialized with 16 significant figures. Is there any way to serialize them using, say, 6 significant figures?

@gregmarr
Copy link
Contributor

gregmarr commented Aug 4, 2017

That would cause values to change in a round trip. Is that really what you want?

@gonzalobenegas
Copy link
Author

Yes, I just don't need that much precision and I want to save storage space.

@gonzalobenegas
Copy link
Author

Maybe by modifying the source code?

@nlohmann
Copy link
Owner

nlohmann commented Aug 8, 2017

There is no parameter for this, and I doubt that adding one would be beneficial for a lot of users. What you could do is to edit function dump_float() and change line

// get number of digits for a text -> float -> text round-trip
static constexpr auto d = std::numeric_limits<number_float_t>::digits10;

to the number of digits you like.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Aug 8, 2017
@gonzalobenegas
Copy link
Author

Thanks, that works for my case!

@psiha
Copy link

psiha commented Oct 4, 2018

Not all text-serialized-JSON usage is about round-triping, e.g. sometimes it is used for structured reports - and printing out all the decimals in a double when you are say presenting benchmark results in milliseconds is just very very ugly noise...
For example with RapidJSON one can say writer.SetMaxDecimalPlaces( 1 )...please consider adding something along those lines (it can even be a compile time option/template parameter as far as I am concerned).

@ziggurat29
Copy link

seconded; I don't need to report time with picosecond precision only to add 50% overhead to my docs. I would prefer a runtime setting.

@nathanieltagg
Copy link

This is a major limitation for my application: it ships a LOT of floating point numbers, and so I have to tune the precision of each number in at least two ways: precision to a certain fractional uncertainty, or precision to a specific decimal-place precision. The goal is maximum precision with fewest characters, so I make liberal use of scientific notation to achieve this in some cases.

To implement my solution in your framework, I just need one hook: the ability to assign an unquoted string. That is:
j['mything'] = json::unquoted_string("1.11")
would yield:
{
mything: 1.11
}

Would this be possible?

@p-i-
Copy link

p-i- commented Jan 23, 2019

I would love something like:
my_json.dump( "pretty_print=true, indent=4, float_decimal_places=2, float_use_scientific_notation=false" )

The option-string would almost be JSON too.

@nathanieltagg
Copy link

@p-i- You can manage that with a custom streamer class, I think. Might be easy to tack on.

@nathanieltagg
Copy link

Thinking more about it, I think the method I use in my hack actually would work for the custom-output thing. You declare a bunch more primative types - instead of just a single floating-point class, you also have a fixed-point-2decimal, fixed-point-3decimal, etc. They act just like the regular float classes during interactions, but the streamer can see them and act accordingly.

Another possibility would be adding to each basic_json another field, which could be an instance of an (empty) struct. The struct template would determine streamer flow, i.e.
struct FixedPoint<2> {}
where template parameters could be used to set options or specificity. This is infinitely expandable and doesn't require an enum like value_t does.... but does increase storage for simple types.

@CraigHutchinson
Copy link

Has a solution to this issue ever been made into the core master?

@t-b
Copy link
Contributor

t-b commented Oct 9, 2019

@CraigHutchinson Nope.

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

9 participants