Implement round-ties-to-even for Duration Debug for consistency with f64

This commit is contained in:
Josh Kaplan 2025-10-08 17:53:52 -04:00
parent e951f470d7
commit f5aec79668
No known key found for this signature in database
GPG key ID: 1D24245906A07E64
2 changed files with 36 additions and 2 deletions

View file

@ -1316,7 +1316,33 @@ impl fmt::Debug for Duration {
// normal floating point numbers. However, we only need to do work
// when rounding up. This happens if the first digit of the
// remaining ones is >= 5.
let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
let integer_part = if fractional_part > 0 && fractional_part == divisor * 5 {
let last_digit_is_odd = if pos > 0 {
(buf[pos - 1] - b'0') % 2 == 1
} else {
// No fractional digits - check the integer part
(integer_part % 2) == 1
};
if last_digit_is_odd {
let mut rev_pos = pos;
let mut carry = true;
while carry && rev_pos > 0 {
rev_pos -= 1;
if buf[rev_pos] < b'9' {
buf[rev_pos] += 1;
carry = false;
} else {
buf[rev_pos] = b'0';
}
}
if carry { integer_part.checked_add(1) } else { Some(integer_part) }
} else {
Some(integer_part)
}
} else if fractional_part > 0 && fractional_part > divisor * 5 {
// Round up the number contained in the buffer. We go through
// the buffer backwards and keep track of the carry.
let mut rev_pos = pos;

View file

@ -439,7 +439,6 @@ fn debug_formatting_precision_two() {
assert_eq!(format!("{:.2?}", Duration::new(4, 001_000_000)), "4.00s");
assert_eq!(format!("{:.2?}", Duration::new(2, 100_000_000)), "2.10s");
assert_eq!(format!("{:.2?}", Duration::new(2, 104_990_000)), "2.10s");
assert_eq!(format!("{:.2?}", Duration::new(2, 105_000_000)), "2.11s");
assert_eq!(format!("{:.2?}", Duration::new(8, 999_999_999)), "9.00s");
}
@ -480,6 +479,15 @@ fn debug_formatting_precision_high() {
assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s");
}
#[test]
fn debug_formatting_round_to_even() {
assert_eq!(format!("{:.0?}", Duration::new(1, 500_000_000)), "2s");
assert_eq!(format!("{:.0?}", Duration::new(2, 500_000_000)), "2s");
assert_eq!(format!("{:.0?}", Duration::new(0, 1_500_000)), "2ms");
assert_eq!(format!("{:.0?}", Duration::new(0, 2_500_000)), "2ms");
assert_eq!(format!("{:.2?}", Duration::new(2, 105_000_000)), "2.10s");
}
#[test]
fn duration_const() {
// test that the methods of `Duration` are usable in a const context