Bunny83 / SimpleJSON

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

BUG: It handle the long/ulong values as a double, and the value changing #53

Closed FemLolStudio closed 9 months ago

FemLolStudio commented 1 year ago

I use it for my Discord bot, and I use thia class for better managing datas what I get from the mysql database. So, when I download the ID of a user and I serialize it than want to get back the user it it give me back a similar, but not the same ID.

Here is a sample code what is my problem:

var results = new Dictionary<string, object>();
results.Add("UlongValue", (ulong)570588935458127888);
var jsonObj = JSON.Parse(JsonConvert.SerializeObject(results, Formatting.None));
Console.WriteLine(jsonObj["UlongValue"].AsULong); //It's give back 570588935458127872
Console.WriteLine(jsonObj["UlongValue"].AsLong); //It's give back 570588935458127872
Console.WriteLine(jsonObj["UlongValue"].Value); //It's give back 5.705889354581279E+17
Console.WriteLine(jsonObj.ToString()); //It's give back {"UlongValue":5.705889354581279E+17}

If I think rigthly it store the data in double, and this is the problem.

Bunny83 commented 1 year ago

This is not a bug. JSON is data type unaware when it comes to numbers. The majority of json frameworks out there uses double values to represent numbers. Javascript only had doubles to begin with. The json standard allows to represent arbitrarily precice numbers. However is also makes it clear that you can not rely on support for that in any compliant parser. That's why the standard recommends to store values that need to retain a greater precision than double as strings.

SimplyJSON actually has this option. That's what the static longAsString option is good for. Though note it only controls the implicit long to JSONNode operator works. It does not change how numbers are parsed in general. If your json contains an actual number that is too large to be represented by a double, you can't load it with this framework. As it is suggested, you should not represent those as numbers but as strings.

IDs in general should not be treated as numbers when you transfer them. So store / return them as strings. in JSON it would be completely valid to store a numeric value like 1000000000 as 1e9. It's numberically the same thing, but as ID it wouldn't make much sense..

Please read the JSON RFC about numbers.