Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Floats are serialized with unnecessary decimal place #562

Closed
nwoltman opened this issue Aug 26, 2019 · 7 comments
Closed

Floats are serialized with unnecessary decimal place #562

nwoltman opened this issue Aug 26, 2019 · 7 comments

Comments

@nwoltman
Copy link

With this struct definition:

#[derive(Serialize)]
struct MyStruct {
    a: f64,
    b: f64,
}

Instantiated like this:

MyStruct {
    a: 1.0,
    b: 1.2
}

serde_json serializes the struct like this:

{
  "a": 1.0,
  "b": 1.2
}

But I'd expect the serialized output to be:

{
  "a": 1,
  "b": 1.2
}

Even though the JSON that serde produces is technically valid, it's different from how most other languages serialize floats, and it's even different from how rust's built-in formatter formats floats: format!("{}", 1.0f64) returns 1.

@ssokolow
Copy link

ssokolow commented Feb 2, 2020

On the other hand, it does provide a hint to languages without implicit integer→float conversion that the value should be deserialized as a float, not an integer. Whether that's useful in a real-world context or a footgun is anybody's guess though.

(The question is how likely such a program is to encounter a whole number during testing rather than production.)

@nwoltman
Copy link
Author

nwoltman commented Feb 3, 2020

it does provide a hint to languages without implicit integer→float conversion that the value should be deserialized as a float, not an integer.

Perhaps that is useful. Maybe there could be an option to choose how the JSON gets formatted?

@dtolnay
Copy link
Member

dtolnay commented Jul 5, 2020

This is intentional, but can be customized by providing a Formatter impl with the behavior you want.
https://docs.rs/serde_json/1.0.56/serde_json/struct.Serializer.html#method.with_formatter

@JaydenElliott
Copy link

JaydenElliott commented Jan 10, 2023

For anyone with this problem but only want to change the behavior of one struct field, the following may be a good alternative to writing your own formatter:

#[derive(Serialize)]
struct Example {
  #[serde(serialize_with = "custom_func")]
  x: f32
}

@tr3ysmith
Copy link

I guess my bigger question to this, is why is this intentional? This isn't common with web based applications. I'm running into an issue right now where I have a rust application talking to a web application and they're trying to compare their JSON payloads byte wise, and this is causing indifferences.

@dtolnay

@fawdlstty
Copy link

I have a question that How to serialize an serde_json::Value object and specify the number of decimal places for all floating-point types inside it?

@nyurik
Copy link

nyurik commented Oct 20, 2024

What's even more concerning is that my struct with f64 floats whose value is 180.0 sometimes serializes to text with an extra .0, and sometimes without it - depending if it runs in GitHub action or on my linux laptop. This makes integration testing much harder as the values are less predictable.

@serde-rs serde-rs locked and limited conversation to collaborators Oct 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

7 participants