mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #2741 from jfinkels/seq-width-negative-decimal
seq: correct width for certain negative decimals
This commit is contained in:
commit
4ada922a4a
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> {
|
fn parse_decimal_no_exponent(s: &str, i: usize) -> Result<PreciseNumber, ParseNumberError> {
|
||||||
let x: BigDecimal = s.parse().map_err(|_| ParseNumberError::Float)?;
|
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);
|
let num_fractional_digits = s.len() - (i + 1);
|
||||||
if is_minus_zero_float(s, &x) {
|
if is_minus_zero_float(s, &x) {
|
||||||
Ok(PreciseNumber::new(
|
Ok(PreciseNumber::new(
|
||||||
|
@ -215,20 +222,26 @@ fn parse_decimal_and_exponent(
|
||||||
let num_integral_digits = {
|
let num_integral_digits = {
|
||||||
let minimum: usize = {
|
let minimum: usize = {
|
||||||
let integral_part: f64 = s[..j].parse().map_err(|_| ParseNumberError::Float)?;
|
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
|
2
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Special case: if the string is "-.1e2", we need to treat it
|
||||||
let total = i as i64 + exponent;
|
// 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 {
|
if total < minimum as i64 {
|
||||||
minimum
|
minimum
|
||||||
} else {
|
} else {
|
||||||
total.try_into().unwrap()
|
total.try_into().unwrap()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let num_fractional_digits = if num_digits_between_decimal_point_and_e < exponent {
|
let num_fractional_digits = if num_digits_between_decimal_point_and_e < exponent {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
@ -532,6 +545,8 @@ mod tests {
|
||||||
assert_eq!(num_integral_digits("123"), 3);
|
assert_eq!(num_integral_digits("123"), 3);
|
||||||
// decimal, no exponent
|
// decimal, no exponent
|
||||||
assert_eq!(num_integral_digits("123.45"), 3);
|
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
|
// exponent, no decimal
|
||||||
assert_eq!(num_integral_digits("123e4"), 3 + 4);
|
assert_eq!(num_integral_digits("123e4"), 3 + 4);
|
||||||
assert_eq!(num_integral_digits("123e-4"), 1);
|
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.45e6"), 3 + 6);
|
||||||
assert_eq!(num_integral_digits("123.45e-6"), 1);
|
assert_eq!(num_integral_digits("123.45e-6"), 1);
|
||||||
assert_eq!(num_integral_digits("123.45e-1"), 2);
|
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
|
// minus zero int
|
||||||
assert_eq!(num_integral_digits("-0e0"), 2);
|
assert_eq!(num_integral_digits("-0e0"), 2);
|
||||||
assert_eq!(num_integral_digits("-0e-0"), 2);
|
assert_eq!(num_integral_digits("-0e-0"), 2);
|
||||||
|
@ -565,6 +586,8 @@ mod tests {
|
||||||
assert_eq!(num_fractional_digits("0xff"), 0);
|
assert_eq!(num_fractional_digits("0xff"), 0);
|
||||||
// decimal, no exponent
|
// decimal, no exponent
|
||||||
assert_eq!(num_fractional_digits("123.45"), 2);
|
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
|
// exponent, no decimal
|
||||||
assert_eq!(num_fractional_digits("123e4"), 0);
|
assert_eq!(num_fractional_digits("123e4"), 0);
|
||||||
assert_eq!(num_fractional_digits("123e-4"), 4);
|
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.45e1"), 1);
|
||||||
assert_eq!(num_fractional_digits("123.45e-6"), 8);
|
assert_eq!(num_fractional_digits("123.45e-6"), 8);
|
||||||
assert_eq!(num_fractional_digits("123.45e-1"), 3);
|
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
|
// minus zero int
|
||||||
assert_eq!(num_fractional_digits("-0e0"), 0);
|
assert_eq!(num_fractional_digits("-0e0"), 0);
|
||||||
assert_eq!(num_fractional_digits("-0e-0"), 0);
|
assert_eq!(num_fractional_digits("-0e-0"), 0);
|
||||||
|
|
|
@ -473,6 +473,15 @@ fn test_width_decimal_scientific_notation_trailing_zeros_increment() {
|
||||||
.no_stderr();
|
.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]
|
#[test]
|
||||||
fn test_width_negative_scientific_notation() {
|
fn test_width_negative_scientific_notation() {
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
|
@ -480,6 +489,54 @@ fn test_width_negative_scientific_notation() {
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_is("-0.001\n00.999\n")
|
.stdout_is("-0.001\n00.999\n")
|
||||||
.no_stderr();
|
.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.
|
/// Test that trailing zeros in the end argument do not contribute to width.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue