kgabis/parson

Excess precision for small floating point numbers.

sgh opened this issue · 16 comments

sgh commented

The following program gives the following output:

{"value":0.59999999999999998}

This is undesireable. How can I avoid it?

int main() {
JSON_Value* json_val = json_value_init_object();
json_object_set_number(json_object(json_val), "value", 0.6);
char* json_str = json_serialize_to_string(json_val);
printf("%s\n", json_str);
json_free_serialized_string(json_str);
json_value_free(json_val);
}

json_set_float_serialization_format was added in af848c2.

sgh commented

In the majority of case you would want a reasonable default "json_set_float_serialization_format" clearly solves that. That is good! But I do not understand by the default serilization format cannot be just be changed. Becasue everyone will now end up throwing a call too json_set_float_serialization_format in main() to force that reasonable default - or am I misunderstanding something?

Sorry, could you explain it more clearly?

sgh commented

The essence is that some numbers I want to output with just 1 decimal. Other I'd like 3 or 4. It is a per situation decision at which resolution to store each number.

Sorry I won't be able to provide this sort of flexibility.

sgh commented

would you accept a pullrequest containing such a feature using an extra function call fx. "json_object_set_number_prec" taking an additional argument containing the desired number of digits?

No, I don't want to add this to the API. Feel free to fork parson and add it though.

sgh commented

Ok. I'm a bit sad about that, especially because parson great and forking leads nowhere good.

sgh commented

I'd like to reopen this issue. The fix you did does not solve the problems for all normal cases.

In my application I many times want to write a number fx. 0.6. This number cannot be represented using a whole binary double precision floating point number. So I get excess decimals.
Given the fact that 0.6 is stored in a single precision float I set the float format to "%1.7g". This is all well and good and my float is serialized to be "0.6".

But, it also turns out that I in my application also serialize numbers which are in microseconds since epoch. And here the problem arises. Current epoch in microseconds is around 1639465384957384. When serialized this ends up as 1.639465e+15 .... which is clearly wrong.

I see a couple of solutions that can solve this.

  1. Allow to specify precision per. number.

  2. Add an int64 number type. Other parsers clearly distinguishes between floating point and integer types - possibly because of this type of case.

What do you think?

1 sounds bad, 2 was raised by multiple people so far, so maybe at some point I should give it a try, but I don't see myself working on it anytime soon (yes, reviewing someone else's code is also work, not far off from writing the code myself). So for now I would consider this a wontfix and if you really need this I still encourage you to fork parson.

sgh commented

Ok - your work efforts in the matter aside. If solution 2 where to be implemented - would you welcome that addition to the API?

I will do the implementation if you are willing to accept it.

As I said, reviewing code is also work, so no.

sgh commented

We are seriously misunderstanding each other during these discussions.

My question is: Would you accept an addition of json_object_set_int64(...) when you have the time to review it?

No, because it would require a bunch of other functions exposed through the api for this functionality to make sense.

As I said, it's a wontfix, please stop creating pull requests related to this issue. I don't have time to work on this issue and please respect that.