diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 8bf6cb008..c4380fd3d 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -67,6 +67,18 @@ impl Number { Number::F64(n) => n, } } + + /// Convert this number into a bigint, consuming it. + /// + /// For floats, this returns the [`BigInt`] corresponding to the + /// floor of the number. + fn into_bigint(self) -> BigInt { + match self { + Number::MinusZero => BigInt::zero(), + Number::F64(x) => BigInt::from(x.floor() as i64), + Number::BigInt(n) => n, + } + } } impl FromStr for Number { @@ -197,25 +209,38 @@ pub fn uumain(args: impl uucore::Args) -> i32 { crash_if_err!(1, slice.parse()) }; + let is_negative_zero_f64 = |x: f64| x == -0.0 && x.is_sign_negative() && largest_dec == 0; let result = match (first, last, increment) { - (Number::MinusZero, Number::BigInt(last), Number::BigInt(increment)) => print_seq_integers( - (BigInt::zero(), increment, last), + // For example, `seq -0 1 2` or `seq -0 1 2.0`. + (Number::MinusZero, last, Number::BigInt(increment)) => print_seq_integers( + (BigInt::zero(), increment, last.into_bigint()), options.separator, options.terminator, options.widths, padding, true, ), - (Number::BigInt(first), Number::BigInt(last), Number::BigInt(increment)) => { + // For example, `seq -0e0 1 2` or `seq -0e0 1 2.0`. + (Number::F64(x), last, Number::BigInt(increment)) if is_negative_zero_f64(x) => { print_seq_integers( - (first, increment, last), + (BigInt::zero(), increment, last.into_bigint()), options.separator, options.terminator, options.widths, padding, - false, + true, ) } + // For example, `seq 0 1 2` or `seq 0 1 2.0`. + (Number::BigInt(first), last, Number::BigInt(increment)) => print_seq_integers( + (first, increment, last.into_bigint()), + options.separator, + options.terminator, + options.widths, + padding, + false, + ), + // For example, `seq 0 0.5 1` or `seq 0.0 0.5 1` or `seq 0.0 0.5 1.0`. (first, last, increment) => print_seq( (first.into_f64(), increment.into_f64(), last.into_f64()), largest_dec, diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index 7a58a950a..51262ff23 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -199,6 +199,16 @@ fn test_preserve_negative_zero_start() { .succeeds() .stdout_is("-0\n1\n") .no_stderr(); + new_ucmd!() + .args(&["-0", "1", "2"]) + .succeeds() + .stdout_is("-0\n1\n2\n") + .no_stderr(); + new_ucmd!() + .args(&["-0", "1", "2.0"]) + .succeeds() + .stdout_is("-0\n1\n2\n") + .no_stderr(); } #[test] @@ -226,6 +236,50 @@ fn test_width_negative_zero() { .succeeds() .stdout_is("-0\n01\n") .no_stderr(); + new_ucmd!() + .args(&["-w", "-0", "1", "2"]) + .succeeds() + .stdout_is("-0\n01\n02\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0", "1", "2.0"]) + .succeeds() + .stdout_is("-0\n01\n02\n") + .no_stderr(); +} + +#[test] +fn test_width_negative_zero_decimal_notation() { + new_ucmd!() + .args(&["-w", "-0.0", "1"]) + .succeeds() + .stdout_is("-0.0\n01.0\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.0", "1.0"]) + .succeeds() + .stdout_is("-0.0\n01.0\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.0", "1", "2"]) + .succeeds() + .stdout_is("-0.0\n01.0\n02.0\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.0", "1", "2.0"]) + .succeeds() + .stdout_is("-0.0\n01.0\n02.0\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.0", "1.0", "2"]) + .succeeds() + .stdout_is("-0.0\n01.0\n02.0\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.0", "1.0", "2.0"]) + .succeeds() + .stdout_is("-0.0\n01.0\n02.0\n") + .no_stderr(); } #[test] @@ -235,29 +289,63 @@ fn test_width_negative_zero_scientific_notation() { .succeeds() .stdout_is("-0\n01\n") .no_stderr(); + new_ucmd!() + .args(&["-w", "-0e0", "1", "2"]) + .succeeds() + .stdout_is("-0\n01\n02\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0e0", "1", "2.0"]) + .succeeds() + .stdout_is("-0\n01\n02\n") + .no_stderr(); new_ucmd!() .args(&["-w", "-0e+1", "1"]) .succeeds() .stdout_is("-00\n001\n") .no_stderr(); + new_ucmd!() + .args(&["-w", "-0e+1", "1", "2"]) + .succeeds() + .stdout_is("-00\n001\n002\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0e+1", "1", "2.0"]) + .succeeds() + .stdout_is("-00\n001\n002\n") + .no_stderr(); new_ucmd!() .args(&["-w", "-0.000e0", "1"]) .succeeds() .stdout_is("-0.000\n01.000\n") .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e0", "1", "2"]) + .succeeds() + .stdout_is("-0.000\n01.000\n02.000\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e0", "1", "2.0"]) + .succeeds() + .stdout_is("-0.000\n01.000\n02.000\n") + .no_stderr(); new_ucmd!() .args(&["-w", "-0.000e-2", "1"]) .succeeds() .stdout_is("-0.00000\n01.00000\n") .no_stderr(); - new_ucmd!() - .args(&["-w", "-0.000e5", "1"]) + .args(&["-w", "-0.000e-2", "1", "2"]) .succeeds() - .stdout_is("-000000\n0000001\n") + .stdout_is("-0.00000\n01.00000\n02.00000\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e-2", "1", "2.0"]) + .succeeds() + .stdout_is("-0.00000\n01.00000\n02.00000\n") .no_stderr(); new_ucmd!() @@ -265,6 +353,32 @@ fn test_width_negative_zero_scientific_notation() { .succeeds() .stdout_is("-000000\n0000001\n") .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e5", "1", "2"]) + .succeeds() + .stdout_is("-000000\n0000001\n0000002\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e5", "1", "2.0"]) + .succeeds() + .stdout_is("-000000\n0000001\n0000002\n") + .no_stderr(); + + new_ucmd!() + .args(&["-w", "-0.000e5", "1"]) + .succeeds() + .stdout_is("-000000\n0000001\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e5", "1", "2"]) + .succeeds() + .stdout_is("-000000\n0000001\n0000002\n") + .no_stderr(); + new_ucmd!() + .args(&["-w", "-0.000e5", "1", "2.0"]) + .succeeds() + .stdout_is("-000000\n0000001\n0000002\n") + .no_stderr(); } #[test]