Bunny83 / SimpleJSON

A simple JSON parser in C#
MIT License
735 stars 294 forks source link

Float - comma,dot problem #9

Closed AlesKriz closed 6 years ago

AlesKriz commented 6 years ago

Code

JSONObject data = new JSONObject();
data.Add("floatTest", 0.11f);
Debug.Log("Result 1: " + data.ToString());
var N = JSON.Parse(data2.ToString());
Debug.Log("Result 2: " + N["floatTest"]);

Log

Result 1:  {"floatTest":0,109999999403954}
Result 2: 0

A. Comma is problem for json formatting. B. Precision?

Bunny83 commented 6 years ago

Yes, by default double.Parse / TryParse / ToString uses your systems default culture. It seems the culture you use uses a comma as decimal point. I always had this in mind but so far i haven't run into any issues yet, even though in my country the comma is also the decimal point. Though i changed the number format on my PC years ago ^^.

I can roll out an update that uses the invariant culture for double value parsing and ToString conversion

Bunny83 commented 6 years ago

Published a quick update. Unfortunately this change might have a GC impact when dealing with many number values when you use ToString. This is due to the fact that the StringBuilder has no GC friendly overload that accepts an IFormatProvider. So i simply format each number "manually" with ToString and add the string to the result.

Though in most cases this shouldn't be too bad. I haven't really tested the changes well to the bone. If you find any trouble or errors, just leave another comment

AlesKriz commented 6 years ago

Yes work it. Thanks.

The second problem I have with cast to double. Can you add float support?

Example: data.Add("floatTest", 0.11f); Result 1: {"floatTest":0.109999999403954}

or

data.Add("floatTest", 0.11d); Result 1: {"floatTest":0.11}

Bunny83 commented 6 years ago

JSON uses by definition double precision floating point numbers. When you store a single precision float it will be converted into double precision automatically. The number 0.11 can not be represented exactly, neither in single nor in double precision. It always need to be rounded.

I recommend to watch this video and maybe play around on this site which let you manipulate single bits in a single precision floating point number.

Have a look at this code snippet:

float f = 0.11f;
double d = f;
Debug.Log(f.ToString());
Debug.Log(d.ToString());

The first log will print "0.11" while the second log will print "0.109999999403954". There is no way to "recover" any precision since double actually has a greater precision and that's why you actually see how the float was actually stored.

If you need any specific formatting you should store the number as string like the JSON format actually suggests.