json: Parser cannot read arbitrary precision numbers

http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf specifies in the second paragraph of the introduction that JSON is agnostic about numbers, and simply represents them as a series of digits.

However, serde-json parses anything with a decimal point as a Rust f64, which causes numbers to be read incorrectly. There is no way to avoid this because this behaviour is chosen as soon as a decimal point is encountered. This makes it impossible to use serde-json to interoperate with financial software using JSON.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 1
  • Comments: 21 (16 by maintainers)

Most upvoted comments

#348 has a promising implementation with the same API as #252 but without relying on unstable specialization. It also interacts better with deserializer “adapters” like erased-serde, serde-ignored, and serde-encrypted-value which would not have worked with specialization.

Sure, here’s a simple test with the current versions:

    let input = r#"{
        "x1": -9876.543210,
        "x2": 0.14,
        "x3": 0.1401,
        "x4": 0.14004,
        "x5": 0.14005
    }"#;

    let json: serde_json::Value = serde_json::from_str(&input).unwrap();
    println!("{}", serde_json::to_string_pretty(&json).unwrap());

    let hjson: serde_hjson::Value = serde_hjson::from_str(&input).unwrap();
    println!("{:?}", hjson);
{
  "x1": -9876.543210000002,
  "x2": 0.14,
  "x3": 0.1401,
  "x4": 0.14004000000000003,
  "x5": 0.14005
}
{
  x1: -9876.54321
  x2: 0.14
  x3: 0.1401
  x4: 0.14004
  x5: 0.14005
}

For hjson I adopted your code to do the testing but then fed the string to str.parse::<f64>().

@nubis Okay but once you parse it, what do you do with the result? The Visitor trait will require you to convert it to f64 in order to do anything.

You are going to need to fix https://github.com/serde-rs/serde/issues/185 before you fix this.