{:2.0} ; {...">

Float Display with fixed precision output uses inconsistent rounding rules · Issue #70336 · rust-lang/rust (original) (raw)

Rust's f32 formatting seems to follow inconsistent rounding rules when rounding to a fixed output precision.

fn main() { for i in 0..=10 { let nf = (i as f32) + 0.5f32; println!("{:4} -> {:2.0} ; {:5} -> {:3.0}", nf, nf, -nf, -nf); } }

Output (Playground):

 0.5 ->  1 ;  -0.5 ->  -1
 1.5 ->  2 ;  -1.5 ->  -2
 2.5 ->  2 ;  -2.5 ->  -2
 3.5 ->  4 ;  -3.5 ->  -4
 4.5 ->  4 ;  -4.5 ->  -4
 5.5 ->  6 ;  -5.5 ->  -6
 6.5 ->  6 ;  -6.5 ->  -6
 7.5 ->  8 ;  -7.5 ->  -8
 8.5 ->  8 ;  -8.5 ->  -8
 9.5 -> 10 ;  -9.5 -> -10
10.5 -> 10 ; -10.5 -> -10

I get this output on Linux x86-64 with both rustc 1.42.0 (b8cedc0 2020-03-09) and rustc 1.44.0-nightly (f509b26 2020-03-18). I have not tested on other systems, and have not yet tested with f64.

Most inputs are rounded following the rule of rounding half to the nearest integer, but 0.5 and -0.5 are rounded away from zero instead.

When rounding 0.5 to an integer both 0 or 1 are correct outputs, so this may not be a bug. However it seems strange that the round-half-to-even rule should be followed for 1.5, 2.5, and up while a different rule is followed for 0.5.

By comparison, my Python and C versions followed round-half-to-even consistently (rounding 0.5 to 0), though I don't know that they provide any guarantee to follow that rule.

Cross-reference: I originally posted about this on the user forum. Rounding mode for fixed precision float Display format?