3

I have an issue with deserializing decimal value.

JObject.Parse("{\"available\":8777.831438322572000}")

If I type this code in VS under debugger the result is

"available": 8777.8314383225716

If I try this

obj.Value<decimal>("available")

the result is 8777.83143832257

Where am I wrong? What api methods should I use to get correct results?

Alew
  • 316
  • 4
  • 12
  • 1
    Possible duplicate of [Handling decimal values in Newtonsoft.Json](https://stackoverflow.com/questions/24051206/handling-decimal-values-in-newtonsoft-json) – mjwills Jul 06 '18 at 09:12

2 Answers2

4

I find out that this problem doesn't relate to methods which take destination type as an argument. In case of untyped version method there is a setting which allows to change how json.net treats string with decimal separator. JsonReader.FloatParseHandling default value is FloatParseHandling.Double In my case the way to get correct results is:

JObject.Load(new JsonTextReader(new StringReader(value)) { FloatParseHandling = FloatParseHandling.Decimal }, null)

JsonSerializer and JsonSerializerSettings contain the same setting.

Alew
  • 316
  • 4
  • 12
  • 1
    You might want to bracket the `JsonTextReader` and `StringReader` in `using` statements. Practically that doesn't matter with `StringReader` but will be a problem with `StreamReader`. – dbc Mar 17 '21 at 14:44
3

The result of JObject.Parse("{\"available\":8777.831438322572000}") is a double. The second statement results in a decimal.

The double has floating point precision, which is not that precise as a decimal.

Required reading: Why Floating-Point Numbers May Lose Precision

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325