diff --git a/src/uu/numfmt/src/format.rs b/src/uu/numfmt/src/format.rs index a6416595b1e..270039728c5 100644 --- a/src/uu/numfmt/src/format.rs +++ b/src/uu/numfmt/src/format.rs @@ -584,8 +584,18 @@ fn consider_suffix( Unit::None => return Ok((n, None)), }; + // The suffix is chosen from the value as it will be printed, so with + // `--round=down` 999.9 stays 999 instead of becoming 0.9k. + let unscaled = if is_precision_specified { + round_with_precision(n, round_method, 0) + } else { + div_round(n, 1.0, round_method) + }; + if unscaled.abs() <= bases[1] - 1.0 { + return Ok((unscaled, None)); + } + let i = match abs_n { - _ if abs_n <= bases[1] - 1.0 => return Ok((n, None)), _ if abs_n < bases[2] => 1, _ if abs_n < bases[3] => 2, _ if abs_n < bases[4] => 3, diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index 036da1c09cc..2ce83c583b5 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -616,6 +616,44 @@ fn test_round_with_to_unit() { } } +#[test] +fn test_round_without_suffix() { + // A value printed without a suffix is rounded with the method too, and + // the suffix is only added if the rounded value needs one. + for (method, exp) in [ + ("from-zero", ["13", "-13", "1.0k", "1.0K"]), + ("towards-zero", ["12", "-12", "999", "1023"]), + ("up", ["13", "-12", "1.0k", "1.0K"]), + ("down", ["12", "-13", "999", "1023"]), + ("nearest", ["12", "-12", "1.0k", "1.0K"]), + ] { + let round = format!("--round={method}"); + new_ucmd!() + .args(&["--to=si", &round, "--", "12.1", "-12.1", "999.9"]) + .succeeds() + .stdout_only(exp[..3].join("\n") + "\n"); + new_ucmd!() + .args(&["--to=iec", &round, "1023.9"]) + .succeeds() + .stdout_only(format!("{}\n", exp[3])); + } + + // With a `--format` precision, the value is rounded to an integer first. + for (method, exp) in [ + ("from-zero", "13.0\n-13.0\n1.0k\n2.0\n"), + ("towards-zero", "12.0\n-12.0\n999.0\n1.0\n"), + ("up", "13.0\n-12.0\n1.0k\n2.0\n"), + ("down", "12.0\n-13.0\n999.0\n1.0\n"), + ("nearest", "12.0\n-12.0\n1.0k\n1.0\n"), + ] { + new_ucmd!() + .args(&["--to=si", "--format=%.1f", &format!("--round={method}")]) + .args(&["--", "12.1", "-12.1", "999.9", "1.44"]) + .succeeds() + .stdout_only(exp); + } +} + #[test] fn test_to_unit_with_unitless_small_value_uses_display_rounding() { new_ucmd!()