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

Feature request: "magic" object attributes with ad-hoc dumping routines. #595

Closed
bstarynk opened this issue Oct 13, 2021 · 1 comment
Closed

Comments

@bstarynk
Copy link

bstarynk commented Oct 13, 2021

Hello all,

A feature potentially useful for RefPerSys, and probably for many other projects using JSON with Jansson

In some JSON objects and some cases, it makes no sense to dump a given JSON number with a lot of digits after the decimal point.

As a concrete example, any JSON value representing some "macroscopic" time or some delay (in seconds) probably do not need all the digits. To be specific, in RefPerSys objects are dumped in JSON and contain their modification time (a bit like in Linux filesystem), and that modification time is only precise to a centisecond. As another example, if a JSON object represent my physical properties in a health related application, it make absolutely no sense to dump my weight (in kilograms) with more than one digit after the decimal point (depending on the time of the day, my weight is about 84kg, but could be 84.5kg or 83.5 kg...). As a third example, a JSON object representing weather data does not need to record the measured temperature with more than a decidegree Celsius of precision: it make no sense to record in JSON that the temperature in Paris today is 8.567°C, dumping { "city": "Paris", "temp": 8.7 } is more than enough.

Notice that JSON_REAL_PRECISION(n) is a global thing. I am suggesting to make it specific to some registered attributes....

So I suggest to add a global hashtable of object attribute name dumping functions.

I am ready to implement that feature if there is a reasonable chance for it to be pushed upstream.

I am thinking of some additional function like void json_register_dump_attribute_flag(const char*attrname, size_t attrflag); and for the weather temperature example I would suggest calling json_register_dump_attribute_flag("temp", JSON_REAL_PRECISION(1));

Regards

Basile Starynkevitch [email protected] and [email protected]
near Paris in France. Personal webpage: http://starynkevitch.net/Basile/index_en.html

bstarynk added a commit to bstarynk/jansson that referenced this issue Oct 13, 2021
@akheron
Copy link
Owner

akheron commented Oct 13, 2021

Hi!

The idea of setting real precision based on the name of object keys is unfortunately not much better than setting it globally with JSON_REAL_PRECISION. What if there are many nested JSON objects and two of them have properties with the same name, but you want to apply precision to only one of them? What about support for numbers inside arrays? Etc.

A correct fix, in my opinion, is in the application side. It's pretty easy to construct a C function that rounds a given float to a certain number of decimal places:

double round_to(double value, unsigned int places) {
  double e = pow(10, places);
  return round(value * e) / e;
}

round_to(12.3456, 2)
/* 12.34 */

Just round the timestamps, weights etc. before encoding them in JSON, and you're done! Except...

There is a problem. Not all number are losslessly representable by floats, so for example 1.1 gets encoded as 1.1000000000000001 by Jansson. To fix this, David Gay's dtoa algorigthm could be used, as mentioned already as early as in #10 (comment). Unless I'm mistaken, the algorithm is available in https://github.com/jwiegley/gdtoa/blob/master/dtoa.c and could be incorporated in Jansson to replace the current sprintf("%.17g") based approach.

@akheron akheron closed this as completed Aug 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants