Skip to content

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

Description

@gonzalobenegas

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

Activity

  1. gregmarr commented on Aug 4, 2017

    @gregmarr
    Contributor

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

  2. gonzalobenegas commented on Aug 4, 2017

    @gonzalobenegas
    Author

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

  3. gonzalobenegas commented on Aug 5, 2017

    @gonzalobenegas
    Author

    Maybe by modifying the source code?

  4. nlohmann commented on Aug 8, 2017

    @nlohmann
    Owner

    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.

  5. gonzalobenegas commented on Aug 8, 2017

    @gonzalobenegas
    Author

    Thanks, that works for my case!

  6. psiha commented on Oct 4, 2018

    @psiha

    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).

  7. ziggurat29 commented on Oct 16, 2018

    @ziggurat29

    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.

  8. nathanieltagg commented on Jan 9, 2019

    @nathanieltagg

    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?

  9. p-i- commented on Jan 23, 2019

    @p-i-

    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.

  10. nathanieltagg commented on Jan 23, 2019

    @nathanieltagg

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

  11. nathanieltagg commented on Jan 23, 2019

    @nathanieltagg

    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.

  12. CraigHutchinson commented on Oct 9, 2019

    @CraigHutchinson

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

  13. t-b commented on Oct 9, 2019

    @t-b
    Contributor
  14. yalov commented on Sep 26, 2024

    @yalov

    The 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
    #1170

  15. RaidenV commented on Oct 5, 2024

    @RaidenV

    This 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.

  16. gregmarr commented on Oct 10, 2024

    @gregmarr
    Contributor

    @RaidenV Do you have sample code showing the error?

  17. lingxd commented on Nov 28, 2024

    @lingxd

    该功能的需求非常强烈,以至于 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

  18. added
    🔮 V4 candidateA feature that should be discussed for the next major release
    on Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: questionsolution: proposed fixa fix for the issue has been proposed and waits for confirmation🔮 V4 candidateA feature that should be discussed for the next major release

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions