mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
uucore: format: num_parser: Add parser for ExtendedBigDecimal
Very simple as the f64 parser actually uses that as intermediary value. Add a few tests too.
This commit is contained in:
parent
d7502e4b2e
commit
71a285468b
1 changed files with 80 additions and 0 deletions
|
@ -168,6 +168,15 @@ impl ExtendedParser for f64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExtendedParser for ExtendedBigDecimal {
|
||||||
|
/// Parse a number as an ExtendedBigDecimal
|
||||||
|
fn extended_parse(
|
||||||
|
input: &str,
|
||||||
|
) -> Result<ExtendedBigDecimal, ExtendedParserError<'_, ExtendedBigDecimal>> {
|
||||||
|
parse(input, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_special_value(
|
fn parse_special_value(
|
||||||
input: &str,
|
input: &str,
|
||||||
negative: bool,
|
negative: bool,
|
||||||
|
@ -316,6 +325,12 @@ fn parse(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use bigdecimal::BigDecimal;
|
||||||
|
|
||||||
|
use crate::format::ExtendedBigDecimal;
|
||||||
|
|
||||||
use super::{ExtendedParser, ExtendedParserError};
|
use super::{ExtendedParser, ExtendedParserError};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -387,6 +402,9 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert!(matches!(f64::extended_parse("1.2.3"),
|
assert!(matches!(f64::extended_parse("1.2.3"),
|
||||||
Err(ExtendedParserError::PartialMatch(f, ".3")) if f == 1.2));
|
Err(ExtendedParserError::PartialMatch(f, ".3")) if f == 1.2));
|
||||||
|
// Minus zero. 0.0 == -0.0 so we explicitly check the sign.
|
||||||
|
assert_eq!(Ok(0.0), f64::extended_parse("-0.0"));
|
||||||
|
assert!(f64::extended_parse("-0.0").unwrap().is_sign_negative());
|
||||||
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("inf"));
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("inf"));
|
||||||
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("+inf"));
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("+inf"));
|
||||||
assert_eq!(Ok(f64::NEG_INFINITY), f64::extended_parse("-inf"));
|
assert_eq!(Ok(f64::NEG_INFINITY), f64::extended_parse("-inf"));
|
||||||
|
@ -409,6 +427,55 @@ mod tests {
|
||||||
assert!(f64::extended_parse(&format!("{}", i64::MIN)).is_ok());
|
assert!(f64::extended_parse(&format!("{}", i64::MIN)).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decimal_extended_big_decimal() {
|
||||||
|
// f64 parsing above already tested a lot of these, just do a few.
|
||||||
|
// Careful, we usually cannot use From<f64> to get a precise ExtendedBigDecimal as numbers like 123.15 cannot be exactly represented by a f64.
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::BigDecimal(
|
||||||
|
BigDecimal::from_str("123").unwrap()
|
||||||
|
)),
|
||||||
|
ExtendedBigDecimal::extended_parse("123")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::BigDecimal(
|
||||||
|
BigDecimal::from_str("123.15").unwrap()
|
||||||
|
)),
|
||||||
|
ExtendedBigDecimal::extended_parse("123.15")
|
||||||
|
);
|
||||||
|
// Very high precision that would not fit in a f64.
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::BigDecimal(
|
||||||
|
BigDecimal::from_str(".150000000000000000000000000000000000001").unwrap()
|
||||||
|
)),
|
||||||
|
ExtendedBigDecimal::extended_parse(".150000000000000000000000000000000000001")
|
||||||
|
);
|
||||||
|
assert!(matches!(
|
||||||
|
ExtendedBigDecimal::extended_parse("nan"),
|
||||||
|
Ok(ExtendedBigDecimal::Nan)
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
ExtendedBigDecimal::extended_parse("-NAN"),
|
||||||
|
Ok(ExtendedBigDecimal::MinusNan)
|
||||||
|
));
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::Infinity),
|
||||||
|
ExtendedBigDecimal::extended_parse("InF")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::MinusInfinity),
|
||||||
|
ExtendedBigDecimal::extended_parse("-iNf")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::zero()),
|
||||||
|
ExtendedBigDecimal::extended_parse("0.0")
|
||||||
|
);
|
||||||
|
assert!(matches!(
|
||||||
|
ExtendedBigDecimal::extended_parse("-0.0"),
|
||||||
|
Ok(ExtendedBigDecimal::MinusZero)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hexadecimal() {
|
fn test_hexadecimal() {
|
||||||
assert_eq!(Ok(0x123), u64::extended_parse("0x123"));
|
assert_eq!(Ok(0x123), u64::extended_parse("0x123"));
|
||||||
|
@ -420,6 +487,13 @@ mod tests {
|
||||||
assert_eq!(Ok(0.5), f64::extended_parse("0x.8"));
|
assert_eq!(Ok(0.5), f64::extended_parse("0x.8"));
|
||||||
assert_eq!(Ok(0.0625), f64::extended_parse("0x.1"));
|
assert_eq!(Ok(0.0625), f64::extended_parse("0x.1"));
|
||||||
assert_eq!(Ok(15.007_812_5), f64::extended_parse("0xf.02"));
|
assert_eq!(Ok(15.007_812_5), f64::extended_parse("0xf.02"));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Ok(ExtendedBigDecimal::BigDecimal(
|
||||||
|
BigDecimal::from_str("0.0625").unwrap()
|
||||||
|
)),
|
||||||
|
ExtendedBigDecimal::extended_parse("0x.1")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -462,6 +536,12 @@ mod tests {
|
||||||
f64::extended_parse("0b100.1"),
|
f64::extended_parse("0b100.1"),
|
||||||
Err(ExtendedParserError::PartialMatch(0f64, "b100.1"))
|
Err(ExtendedParserError::PartialMatch(0f64, "b100.1"))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
assert!(match ExtendedBigDecimal::extended_parse("0b100.1") {
|
||||||
|
Err(ExtendedParserError::PartialMatch(ebd, "b100.1")) =>
|
||||||
|
ebd == ExtendedBigDecimal::zero(),
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue