Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ macro_rules! impl_Exp {
n /= 10;
exponent += 1;
}

let (added_precision, subtracted_precision) = match f.precision() {
Some(fmt_prec) => {
// number of decimal digits minus 1
Expand All @@ -331,9 +330,15 @@ macro_rules! impl_Exp {
let rem = n % 10;
n /= 10;
exponent += 1;
// round up last digit
if rem >= 5 {
// round up last digit, round to even on a tie
if rem > 5 || (rem == 5 && (n % 2 != 0 || subtracted_precision > 1 )) {
n += 1;
// if the digit is rounded to the next power
// instead adjust the exponent
if n.ilog10() > (n - 1).ilog10() {
n /= 10;
exponent += 1;
}
}
}
(n, exponent, exponent, added_precision)
Expand Down
20 changes: 16 additions & 4 deletions library/core/tests/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,28 +128,40 @@ fn test_format_int_exp_precision() {
let big_int: u32 = 314_159_265;
assert_eq!(format!("{big_int:.1e}"), format!("{:.1e}", f64::from(big_int)));

//test adding precision
// test adding precision
assert_eq!(format!("{:.10e}", i8::MIN), "-1.2800000000e2");
assert_eq!(format!("{:.10e}", i16::MIN), "-3.2768000000e4");
assert_eq!(format!("{:.10e}", i32::MIN), "-2.1474836480e9");
assert_eq!(format!("{:.20e}", i64::MIN), "-9.22337203685477580800e18");
assert_eq!(format!("{:.40e}", i128::MIN), "-1.7014118346046923173168730371588410572800e38");

//test rounding
// test rounding
assert_eq!(format!("{:.1e}", i8::MIN), "-1.3e2");
assert_eq!(format!("{:.1e}", i16::MIN), "-3.3e4");
assert_eq!(format!("{:.1e}", i32::MIN), "-2.1e9");
assert_eq!(format!("{:.1e}", i64::MIN), "-9.2e18");
assert_eq!(format!("{:.1e}", i128::MIN), "-1.7e38");

//test huge precision
// test huge precision
assert_eq!(format!("{:.1000e}", 1), format!("1.{}e0", "0".repeat(1000)));
//test zero precision
assert_eq!(format!("{:.0e}", 1), format!("1e0",));
assert_eq!(format!("{:.0e}", 35), format!("4e1",));

//test padding with precision (and sign)
// test padding with precision (and sign)
assert_eq!(format!("{:+10.3e}", 1), " +1.000e0");

// test precision remains correct when rounding to next power

for i in i16::MIN..=i16::MAX {
for p in 0..=5 {
assert_eq!(
format!("{i:.p$e}"),
format!("{:.p$e}", f32::from(i)),
"integer {i} at precision {p}"
);
}
}
}

#[test]
Expand Down