1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

uucore: format: num_parser: Fix large hexadecimal float parsing

Large numbers can overflow u64 when doing 16u64.pow(scale):
do the operation on BigInt/BigDecimal instead.

Also, add a test. Wolfram Alpha can help confirm the decimal number
is correct (16-16**-21).
This commit is contained in:
Nicolas Boichat 2025-03-19 21:29:11 +01:00
parent b5a658528b
commit 55773e9d35

View file

@ -306,7 +306,8 @@ fn parse(
BigDecimal::from_bigint(signed_digits, scale)
} else {
// Base is not 10, init at scale 0 then divide by base**scale.
BigDecimal::from_bigint(signed_digits, 0) / (base as u64).pow(scale as u32)
BigDecimal::from_bigint(signed_digits, 0)
/ BigDecimal::from_bigint(BigInt::from(base as u32).pow(scale as u32), 0)
};
ExtendedBigDecimal::BigDecimal(bd)
};
@ -494,6 +495,14 @@ mod tests {
)),
ExtendedBigDecimal::extended_parse("0x.1")
);
// Precisely parse very large hexadecimal numbers (i.e. with a large division).
assert_eq!(
Ok(ExtendedBigDecimal::BigDecimal(
BigDecimal::from_str("15.999999999999999999999999948301211715435770320536956745627321652136743068695068359375").unwrap()
)),
ExtendedBigDecimal::extended_parse("0xf.fffffffffffffffffffff")
);
}
#[test]