Repository navigation
Is there a way to control the precision of serialized floating point numbers? #677
Description
Activity
That would cause values to change in a round trip. Is that really what you want?
Yes, I just don't need that much precision and I want to save storage space.
Maybe by modifying the source code?
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.
Reacted by Bastian Jäger- addedsolution: proposed fixa fix for the issue has been proposed and waits for confirmationa fix for the issue has been proposed and waits for confirmation
on Aug 8, 2017 Thanks, that works for my case!
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).Reacted by Niels Lohmann, Chengcheng Tang, Michele Pratusevich, Pi, Calle Olsen, Craig Hutchinson, DJHoltkamp, wardw, Haochen, Joe Griffin and 11 moreReacted by ziggurat29, Michał Antoszkiewicz, Alexander Yalov and arroyo-plseconded; I don't need to report time with picosecond precision only to add 50% overhead to my docs. I would prefer a runtime setting.
Reacted by Craig Hutchinson and HaochenThis 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?
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.
@p-i- You can manage that with a custom streamer class, I think. Might be easy to tack on.
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.Has a solution to this issue ever been made into the core master?
@CraigHutchinson Nope.
Reacted by Craig Hutchinson, Anton Bernatskiy, Matt Vollrath, kosyan2917, Michał Antoszkiewicz, Tiago Furtado, Kyle Kovacs, Yoshqu and arroyo-plThe feature is so highly requested, that ChatGPT belives it's already there ;)
// CHATGPT GENERATED, WILL NOT WORK #include <iostream> #include <nlohmann/json.hpp> int main() { // Create a JSON object nlohmann::json j; j["pi"] = 3.14159265358979323846; j["e"] = 2.718281828459045; // Serialize JSON with custom precision (indentation level 4 and ensure_precision enabled) std::cout << j.dump(4, ' ', false, nlohmann::json::error_handler_t::strict, 4) << '\n'; return 0; }
@nlohmann is there any possibility that you'll reconsider the feature request based on the support #677 (comment) , and
#1170Reacted by Elvisass, hokori, Aldhra, duolanda, Oliver Kuckertz and ShervinThis needs some sort of fix. Translation from an easily representable floating point number like 1100.000 gets corrupted to 1099.9999999999989 when translating to JSON.
@RaidenV Do you have sample code showing the error?
该功能的需求非常强烈,以至于 ChatGPT 认为它已经存在了 ;)
// CHATGPT GENERATED, WILL NOT WORK #include <iostream> #include <nlohmann/json.hpp> int main() { // Create a JSON object nlohmann::json j; j["pi"] = 3.14159265358979323846; j["e"] = 2.718281828459045; // Serialize JSON with custom precision (indentation level 4 and ensure_precision enabled) std::cout << j.dump(4, ' ', false, nlohmann::json::error_handler_t::strict, 4) << '\n'; return 0; }
@nlohmann 您是否有可能根据支持#677(评论)和 #1170重新考虑该功能请求
I really need this function
Reacted by fettahyildizz, MaxLastBreath, cherrydev, Thomas Willberger and ShervinReacted by Shunz Dai and MaxLastBreath- added🔮 V4 candidateA feature that should be discussed for the next major releaseA feature that should be discussed for the next major release
on Nov 28, 2024
I currently see doubles are being serialized with 16 significant figures. Is there any way to serialize them using, say, 6 significant figures?