-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
document that std::fmt uses ROUND_HALF_EVEN #112742
Comments
I tested it on Playground and it is indeed related to Odd and Even. fn main() {
println!("{:.0}", 12.5f64);
println!("{:.0}", 11.5f64);
println!("{:.0}", 10.5f64);
println!("{:.0}", 9.5f64);
println!("{:.0}", 8.5f64);
println!("{:.0}", 7.5f64);
} this will print: 12
12
10
10
8
8 |
@rustbot claim |
Is it a bug though? Ties to even seems to be the recommended default of IEEE754 for floating point. |
As a side-note: IMHO, duplicating the description of floating point math to the documentation of Rust formatting facilities looks like an overkill as there are numerous quircks. |
outputs "10 11" in godbolt with both gcc and clang. Could be dependent on the libc implementation though of course. I can't find anything in C documentation that mentions the rounding strategy either |
In any case I would say it's quite unexpected both for rust and for c that calling round() produces a different result than printing the number with a precision of zero. It really does seem worth mentioning in documentation |
Looks like someone has already done the research for us and found out that it's inconsistent in C and in tons of other languages as well, not only between languages but also between platforms using the same language. For example, it says that MSVC does rounding away from zero (see also https://stackoverflow.com/questions/10357192/printf-rounding-behavior-for-doubles - that's how I found that article) |
I found this: println!("{:.1}", 3.33f64); // 3.3
println!("{:.1}", -3.33f64); // -3.3
println!("{:.1}", -3.55f64); // -3.5
println!("{:.1}", 4.54f64); // 4.5
println!("{:.1}", 4.55f64); // 4.5
println!("{:.1}", 4.56f64); // 4.6
println!("{:.1}", -4.54f64); // -4.5
println!("{:.1}", -4.55f64); // -4.5
println!("{:.1}", -4.56f64); // -4.6
println!("{:.1}", -5.74f64); // -5.7
println!("{:.1}", -5.75f64); // -5.8
println!("{:.1}", -5.76f64); // -5.8
I'm confused, I think |
I'm investigating the source code of this: rust/library/core/tests/fmt/float.rs Lines 28 to 85 in aa9837b
|
|
@rustbot claim |
I'm going to close as I believe this is resolved by #120967. Please let us know if this should be kept open. |
I tried this code:
I expected to see this happen: It prints 11
Instead, this happened: It prints 10
As far as I am able to find 10.5 has a perfect (lossless) representation in f64-space so it does not seem to be because of floating point error to me.
If I put in 9.5 instead it does work as expected (it prints 10), which is weird because that also has a perfect representation as f64. Is it applying a round_ties_even() kind of logic? If it is then I would expect this to be documented e.g. under https://doc.rust-lang.org/std/fmt/#precision
Meta
I've been using rust playground, rust version 1.70.0
The text was updated successfully, but these errors were encountered: