Boost JSON serialization format (boost 1.76.0)

Viewed 674

How to control the serialization format in the boost json library. I am trying to serialize this object and the floats are being output in scientific notation. How to output in fixed notation like 12000000 instead of 1.2E7? And 0 instead of 0E0.

i.e.

{"id":"de69041b-141b-4e01-b349-458f26f08259","price":3.343403E12,"qty":1.2E7}
{"id":"de69041b-141b-4e01-b349-458f26f08259","price":0E0,"qty":0E0}

Here is a minimal program that will output floats in exponential format (ubuntu 20.04, g++ 9.3.0, boost 1.76.0)

#include <iostream>
#include <boost/json/src.hpp>

using namespace std;
namespace bj = boost::json;

int main(void)
{
    bj::object obj1 = {
        {"id", 1},
        {"price", 3343403000000.00},
        {"qty", 13546000000000.00}
    };

    bj::object obj2 = {
        {"id", 2},
        {"price", 0.0},
        {"qty", 0.0}
    };
    cout << "obj1:" << bj::serialize(obj1) << endl;
    cout << "obj2:" << bj::serialize(obj2) << endl;

    return 0;
}

Output:

obj1:{"id":1,"price":3.343403E12,"qty":1.3546E13}
obj2:{"id":2,"price":0E0,"qty":0E0}
2 Answers

To the best of my knowledge that is not a feature. There has been a fair bit of discussion on the boost mailing list when the library was being reviewed prior to acceptance, so if you want you can check the archives for the rationale.

My recollection of it is that the library focuses on a narrow featureset facilitating machine-to-machine transport (99% of JSON, e.g. in restful APIs). That implies a focus on

  • making it correct
  • making it fast

The same thing came up a day or so ago: Is there a way to switch boost::json::serializer to beautified output? (where I quote from the documentation intro section)

The only thing I can think of is to hack on the existing PrettyPrint example, and modifying the double output section to change the formatting.

  case json::kind::double_:
    os << jv.get_double();
    break;

This question showed how to do it The Old Way, as well as something new in C++20:

Add some stream formatting to taste:

  #include <iomanip>

  case json::kind::double_:
    os << std::fixed << std::setw(10) << std::setprecision(5)
       << jv.get_double();
    break;

or the new-fangled

  case json::kind::double_:
    os << std::format("{:10.5}", jv.get_double());
    break;
Related