mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
seq: correct width for certain negative decimals
Fix a bug in which a negative decimal input would not be displayed with the correct width in the output. Before this commit, the output was incorrectly $ seq -w -.1 .1 .11 -0.1 0.0 0.1 After this commit, the output is correctly $ seq -w -.1 .1 .11 -0.1 00.0 00.1 The code was failing to take into account that the input decimal "-.1" needs to be displayed with a leading zero, like "-0.1".
This commit is contained in:
parent
5c0adb26a5
commit
294bde8e08
2 changed files with 90 additions and 4 deletions
|
@ -172,7 +172,14 @@ fn parse_exponent_no_decimal(s: &str, j: usize) -> Result<PreciseNumber, ParseNu
|
|||
/// ```
|
||||
fn parse_decimal_no_exponent(s: &str, i: usize) -> Result<PreciseNumber, ParseNumberError> {
|
||||
let x: BigDecimal = s.parse().map_err(|_| ParseNumberError::Float)?;
|
||||
let num_integral_digits = i;
|
||||
|
||||
// The number of integral digits is the number of chars until the period.
|
||||
//
|
||||
// This includes the negative sign if there is one. Also, it is
|
||||
// possible that a number is expressed as "-.123" instead of
|
||||
// "-0.123", but when we display the number we want it to include
|
||||
// the leading 0.
|
||||
let num_integral_digits = if s.starts_with("-.") { i + 1 } else { i };
|
||||
let num_fractional_digits = s.len() - (i + 1);
|
||||
if is_minus_zero_float(s, &x) {
|
||||
Ok(PreciseNumber::new(
|
||||
|
@ -215,20 +222,26 @@ fn parse_decimal_and_exponent(
|
|||
let num_integral_digits = {
|
||||
let minimum: usize = {
|
||||
let integral_part: f64 = s[..j].parse().map_err(|_| ParseNumberError::Float)?;
|
||||
if integral_part == -0.0 && integral_part.is_sign_negative() {
|
||||
if integral_part.is_sign_negative() {
|
||||
2
|
||||
} else {
|
||||
1
|
||||
}
|
||||
};
|
||||
|
||||
let total = i as i64 + exponent;
|
||||
// Special case: if the string is "-.1e2", we need to treat it
|
||||
// as if it were "-0.1e2".
|
||||
let total = if s.starts_with("-.") {
|
||||
i as i64 + exponent + 1
|
||||
} else {
|
||||
i as i64 + exponent
|
||||
};
|
||||
if total < minimum as i64 {
|
||||
minimum
|
||||
} else {
|
||||
total.try_into().unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let num_fractional_digits = if num_digits_between_decimal_point_and_e < exponent {
|
||||
0
|
||||
} else {
|
||||
|
@ -532,6 +545,8 @@ mod tests {
|
|||
assert_eq!(num_integral_digits("123"), 3);
|
||||
// decimal, no exponent
|
||||
assert_eq!(num_integral_digits("123.45"), 3);
|
||||
assert_eq!(num_integral_digits("-0.1"), 2);
|
||||
assert_eq!(num_integral_digits("-.1"), 2);
|
||||
// exponent, no decimal
|
||||
assert_eq!(num_integral_digits("123e4"), 3 + 4);
|
||||
assert_eq!(num_integral_digits("123e-4"), 1);
|
||||
|
@ -540,6 +555,12 @@ mod tests {
|
|||
assert_eq!(num_integral_digits("123.45e6"), 3 + 6);
|
||||
assert_eq!(num_integral_digits("123.45e-6"), 1);
|
||||
assert_eq!(num_integral_digits("123.45e-1"), 2);
|
||||
assert_eq!(num_integral_digits("-0.1e0"), 2);
|
||||
assert_eq!(num_integral_digits("-0.1e2"), 4);
|
||||
assert_eq!(num_integral_digits("-.1e0"), 2);
|
||||
assert_eq!(num_integral_digits("-.1e2"), 4);
|
||||
assert_eq!(num_integral_digits("-1.e-3"), 2);
|
||||
assert_eq!(num_integral_digits("-1.0e-4"), 2);
|
||||
// minus zero int
|
||||
assert_eq!(num_integral_digits("-0e0"), 2);
|
||||
assert_eq!(num_integral_digits("-0e-0"), 2);
|
||||
|
@ -565,6 +586,8 @@ mod tests {
|
|||
assert_eq!(num_fractional_digits("0xff"), 0);
|
||||
// decimal, no exponent
|
||||
assert_eq!(num_fractional_digits("123.45"), 2);
|
||||
assert_eq!(num_fractional_digits("-0.1"), 1);
|
||||
assert_eq!(num_fractional_digits("-.1"), 1);
|
||||
// exponent, no decimal
|
||||
assert_eq!(num_fractional_digits("123e4"), 0);
|
||||
assert_eq!(num_fractional_digits("123e-4"), 4);
|
||||
|
@ -575,6 +598,12 @@ mod tests {
|
|||
assert_eq!(num_fractional_digits("123.45e1"), 1);
|
||||
assert_eq!(num_fractional_digits("123.45e-6"), 8);
|
||||
assert_eq!(num_fractional_digits("123.45e-1"), 3);
|
||||
assert_eq!(num_fractional_digits("-0.1e0"), 1);
|
||||
assert_eq!(num_fractional_digits("-0.1e2"), 0);
|
||||
assert_eq!(num_fractional_digits("-.1e0"), 1);
|
||||
assert_eq!(num_fractional_digits("-.1e2"), 0);
|
||||
assert_eq!(num_fractional_digits("-1.e-3"), 3);
|
||||
assert_eq!(num_fractional_digits("-1.0e-4"), 5);
|
||||
// minus zero int
|
||||
assert_eq!(num_fractional_digits("-0e0"), 0);
|
||||
assert_eq!(num_fractional_digits("-0e-0"), 0);
|
||||
|
|
|
@ -473,6 +473,15 @@ fn test_width_decimal_scientific_notation_trailing_zeros_increment() {
|
|||
.no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_width_negative_decimal_notation() {
|
||||
new_ucmd!()
|
||||
.args(&["-w", "-.1", ".1", ".11"])
|
||||
.succeeds()
|
||||
.stdout_is("-0.1\n00.0\n00.1\n")
|
||||
.no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_width_negative_scientific_notation() {
|
||||
new_ucmd!()
|
||||
|
@ -480,6 +489,54 @@ fn test_width_negative_scientific_notation() {
|
|||
.succeeds()
|
||||
.stdout_is("-0.001\n00.999\n")
|
||||
.no_stderr();
|
||||
new_ucmd!()
|
||||
.args(&["-w", "-1.e-3", "1"])
|
||||
.succeeds()
|
||||
.stdout_is("-0.001\n00.999\n")
|
||||
.no_stderr();
|
||||
new_ucmd!()
|
||||
.args(&["-w", "-1.0e-4", "1"])
|
||||
.succeeds()
|
||||
.stdout_is("-0.00010\n00.99990\n")
|
||||
.no_stderr();
|
||||
new_ucmd!()
|
||||
.args(&["-w", "-.1e2", "10", "100"])
|
||||
.succeeds()
|
||||
.stdout_is(
|
||||
"-010
|
||||
0000
|
||||
0010
|
||||
0020
|
||||
0030
|
||||
0040
|
||||
0050
|
||||
0060
|
||||
0070
|
||||
0080
|
||||
0090
|
||||
0100
|
||||
",
|
||||
)
|
||||
.no_stderr();
|
||||
new_ucmd!()
|
||||
.args(&["-w", "-0.1e2", "10", "100"])
|
||||
.succeeds()
|
||||
.stdout_is(
|
||||
"-010
|
||||
0000
|
||||
0010
|
||||
0020
|
||||
0030
|
||||
0040
|
||||
0050
|
||||
0060
|
||||
0070
|
||||
0080
|
||||
0090
|
||||
0100
|
||||
",
|
||||
)
|
||||
.no_stderr();
|
||||
}
|
||||
|
||||
/// Test that trailing zeros in the end argument do not contribute to width.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue