Rounding mode for fixed precision float Display format?

When displaying a floating point value as a fixed precision decimal, it is sometimes necessary to round the value. There are many possible rounding modes, and I expected that fixed precision output would follow one of them. But it looks like it is a mixture of modes instead?

For example:

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);
  }
}

(Playground)

Output:

 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

For values 1.5 through 10.5 this appears to follow round-half-to-even, which seems reasonable (this is the default IEEE 754 rounding mode I think). However, for 0.5 the value is instead rounded away from zero.

Note that all the input values are exactly representable in f32 so this is not a case of the input value being something different to what's in the source code as in question 10235 (this would have been a link to the question, but new users aren't allowed to use more than 2 links, so constructing the forum URL is left as an exercise for the reader.)

Am I missing something? Is this a bug in the standard library?

Edit 2020-03-23: Now raised as Issue #70336.

I could be wrong but I don't think that there are any guarantees for how the string formatting code for floats works, other than it will print some representation of the number. At least I can't find it documented anywhere. But yes, that does seem like odd behaviour.

It might be worth opening an issue on the Rust repository if you're up for it. If you also feel like exploring the code, you might want to start here which I think leads to the grisu algorithm (with a dragon fallback). But I'm not familiar with how these work or what the expected behaviour is.

Thanks. I've opened Issue #70336 for this.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.