mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
seq: Accept underflow in parameters
Also, add a test to check that a very, very, small number is treated as 0. That's probably undefined behaviour, but it does make some sense.
This commit is contained in:
parent
686f1c7841
commit
84e5ee4b86
2 changed files with 21 additions and 3 deletions
|
@ -11,7 +11,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use uucore::format::num_parser::ExtendedParser;
|
use uucore::format::num_parser::{ExtendedParser, ExtendedParserError};
|
||||||
|
|
||||||
use crate::number::PreciseNumber;
|
use crate::number::PreciseNumber;
|
||||||
use uucore::format::ExtendedBigDecimal;
|
use uucore::format::ExtendedBigDecimal;
|
||||||
|
@ -61,8 +61,9 @@ fn compute_num_integral_digits(input: &str, _number: &BigDecimal) -> usize {
|
||||||
// If there is an exponent, reparse that (yes this is not optimal,
|
// If there is an exponent, reparse that (yes this is not optimal,
|
||||||
// but we can't necessarily exactly recover that from the parsed number).
|
// but we can't necessarily exactly recover that from the parsed number).
|
||||||
if parts.len() == 2 {
|
if parts.len() == 2 {
|
||||||
let exp = parts[1].parse::<i64>().unwrap();
|
let exp = parts[1].parse::<i64>().unwrap_or(0);
|
||||||
// For positive exponents, effectively expand the number. Ignore negative exponents.
|
// For positive exponents, effectively expand the number. Ignore negative exponents.
|
||||||
|
// Also ignore overflowed exponents (default 0 above).
|
||||||
if exp > 0 {
|
if exp > 0 {
|
||||||
digits + exp as usize
|
digits + exp as usize
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,6 +81,7 @@ impl FromStr for PreciseNumber {
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
let ebd = match ExtendedBigDecimal::extended_parse(input) {
|
let ebd = match ExtendedBigDecimal::extended_parse(input) {
|
||||||
Ok(ebd) => ebd,
|
Ok(ebd) => ebd,
|
||||||
|
Err(ExtendedParserError::Underflow(ebd)) => ebd, // Treat underflow as 0
|
||||||
Err(_) => return Err(ParseNumberError::Float),
|
Err(_) => return Err(ParseNumberError::Float),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,7 +97,11 @@ impl FromStr for PreciseNumber {
|
||||||
ExtendedBigDecimal::Nan | ExtendedBigDecimal::MinusNan => {
|
ExtendedBigDecimal::Nan | ExtendedBigDecimal::MinusNan => {
|
||||||
return Err(ParseNumberError::Nan);
|
return Err(ParseNumberError::Nan);
|
||||||
}
|
}
|
||||||
ExtendedBigDecimal::BigDecimal(ref bd) => bd.clone(),
|
ExtendedBigDecimal::BigDecimal(ref bd) => {
|
||||||
|
// TODO: `seq` treats small numbers < 1e-4950 as 0, we could do the same
|
||||||
|
// to avoid printing senselessly small numbers.
|
||||||
|
bd.clone()
|
||||||
|
}
|
||||||
ExtendedBigDecimal::MinusZero => BigDecimal::zero(),
|
ExtendedBigDecimal::MinusZero => BigDecimal::zero(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -911,6 +911,18 @@ fn test_parse_out_of_bounds_exponents() {
|
||||||
.args(&["1e-9223372036854775808"])
|
.args(&["1e-9223372036854775808"])
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_only("");
|
.stdout_only("");
|
||||||
|
|
||||||
|
// GNU seq supports arbitrarily small exponents (and treats the value as 0).
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["1e-922337203685477580800000000", "1"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("0\n1\n");
|
||||||
|
|
||||||
|
// Check we can also underflow to -0.0.
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-1e-922337203685477580800000000", "1"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("-0\n1\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue