-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
make number serialzation precision configurable #4591
base: develop
Are you sure you want to change the base?
make number serialzation precision configurable #4591
Conversation
58cbed7
to
954b534
Compare
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated. @maddanio |
1 similar comment
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated. @maddanio |
b7fbcdd
to
42c5426
Compare
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated. @maddanio |
@@ -1272,10 +1272,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec | |||
string_t dump(const int indent = -1, | |||
const char indent_char = ' ', | |||
const bool ensure_ascii = false, | |||
const error_handler_t error_handler = error_handler_t::strict) const | |||
const error_handler_t error_handler = error_handler_t::strict, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to #4513 (comment) where a bjdata_config_t
type was discussed to control the BJData serialization, I think it is also long time to have such a time for the JSON serialization as the parameters start piling up. I'm hesitant to say if this is the last parameter to add before such a config type is introduced, or the first one where we stop the madness...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so mine is one too much? :) but sure, I understand, will look into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, hang on, isnt that a public api breaking change? so you want me to change the public api? or add an overload?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so mine is one too much? :) but sure, I understand, will look into it
Many others before you have been "one too much" and thus haven't been done. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There has been so many discussions about tweaking every last aspect of serializations that adding parameters is getting out of hand.
@@ -832,6 +833,8 @@ class serializer | |||
|
|||
// the actual conversion | |||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) | |||
char format[100]; | |||
snprintf(format, 100, "%%.%dg", precision); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is format
used? Is snprintf
really necessary? Maybe check out details::concat
from detail/string_concat.hpp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume it was supposed to replace "%.*g"
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should instead just do ..."%*.*g", precision, d, x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also means that precision
should be int
instead of size_t
. There is no reason for it to be larger than int
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's the wrong position, that's width. We already specify precision as d
, so a defined precision
override just replaces the existing d
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, on it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized i did not test this path. can you point me to another test that actually provides a non-ieee float?
thanks for looking at this. so does that mean this PR will get merged when I address all of the requests? I was submitting it a bit speculatively and dont want to sink work if thats not the case or more principal discussion is needed first |
42c5426
to
6add13a
Compare
@nlohmann has the final say here on whether this can go forward. Prior to that, I think it would be good to define what exactly precision means here. Is it the maximum number of digits after the decimal point, or the exact number? Having it mean exact is more involved, as it can change a current One reason I recommended using Then the next question is whether |
include/nlohmann/json.hpp
Outdated
const bool pretty_print = o.width() > 0; | ||
const auto indentation = pretty_print ? o.width() : 0; | ||
const bool pretty_print = o.width > 0; | ||
const auto indentation = pretty_print ? o.width : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't quite revert this properly, missing the ()
.
About the maximum or exact and truncation vs rounding:
This prints
|
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated. @maddanio |
I am very hesitant, and these are just my thoughts right now:
Sorry for this rough brain-dump. I will not be able to make any decision right now. But I think I will not add this without having a clear plan how serialization can be improved conceptually before adding some more ifs here and there. |
I forgot one thing that other libraries do that avoids some of the confusion I see in issues here: they store the original input string and only convert it to a number on demand. As a result, parsing is cheaper and you can create the exact serialization of the input. Not sure if we want to do this here, but a "precision = keep whatever precision I put in" requirement is also thinkable. |
I dont think performance difference is measurable, the only action is changing some pointers and doing some comparisons. if any I would surmise performance improves with lower precision. yes, it is truncating, so if you want rounding that would be more involved. but if desired I would be willing to dig in. all in all we in my company really want this, because we have some rather large sets of numbers in json, and this saves us a rather large amount of space and noise. but if you don't think this is what the library needs we will just continue on our fork. and I fully understand how float works, but I also know in many cases the number of digits I really need, and what is just noise (in physics when we calculated stuff we rarely kept more than 3 significant digits :)) |
Signed-off-by: Daniel Oberhoff <[email protected]>
Signed-off-by: Daniel Oberhoff <[email protected]>
Signed-off-by: Daniel Oberhoff <[email protected]>
6add13a
to
0132248
Compare
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated. @maddanio |
This PR adds the possibility to control floating point serialization precision via std::setprecision. I also have a version with an explicit annotator instead if you absolutely want to avoid behaviour changes (as users may have inadvertedly modified the iostate in their code right now), but I find this way much more natural (I was quite suprised that std::setprecision had no effect).
Pull request checklist
Read the Contribution Guidelines for detailed information.
include/nlohmann
directory, runmake amalgamate
to create the single-header filessingle_include/nlohmann/json.hpp
andsingle_include/nlohmann/json_fwd.hpp
. The whole process is described here.