fix for float parsing of exactly 10.0

This commit is contained in:
2025-07-18 21:19:30 +01:00
parent 3cdd512e8b
commit f147abda5f
2 changed files with 33 additions and 4 deletions

View File

@@ -19,7 +19,7 @@ impl Display for StackCalcError {
match self { match self {
StackCalcError::StackOverflow => f.write_str("stack overflow"), StackCalcError::StackOverflow => f.write_str("stack overflow"),
StackCalcError::StackUnderflow => f.write_str("stack underflow"), StackCalcError::StackUnderflow => f.write_str("stack underflow"),
StackCalcError::DecimalError(de) => de.fmt(f), StackCalcError::DecimalError(de) => Display::fmt(de, f),
} }
} }
} }
@@ -185,4 +185,13 @@ mod tests {
)); ));
Ok(()) Ok(())
} }
#[test]
fn test_add_10() -> Result<(), StackCalcError> {
let mut calc = StackCalc::<f64, 3, 5>::default();
calc.push(Decimal::new(false, [3, 0, 0, 0, 0], false, 0))?;
calc.push(Decimal::new(false, [7, 0, 0, 0, 0], false, 0))?;
assert_eq!(calc.add()?, Decimal::new(false, [1, 0, 0, 0, 0], false, 1));
Ok(())
}
} }

View File

@@ -81,7 +81,7 @@ impl<const SIZE: usize, EXP: PrimInt + Unsigned> Decimal<SIZE, EXP> {
} }
let mut exponent: EXP = zero(); let mut exponent: EXP = zero();
let minus_exponent = f < one() && f > zero(); let minus_exponent = f < one() && f > zero();
while f > F::from(10).unwrap() { while f >= F::from(10).unwrap() {
f = f / F::from(10).unwrap(); f = f / F::from(10).unwrap();
exponent = exponent exponent = exponent
.checked_add(&one()) .checked_add(&one())
@@ -234,6 +234,11 @@ mod tests {
use super::*; use super::*;
use arrayvec::ArrayString; use arrayvec::ArrayString;
fn round_f(f: f64, d: i32) -> f64 {
let m = 10.0.powi(d);
(f * m).round() / m
}
#[test] #[test]
fn float_to_decimal_zero() { fn float_to_decimal_zero() {
let dec = Decimal::<5>::try_from(0.0).unwrap(); let dec = Decimal::<5>::try_from(0.0).unwrap();
@@ -243,6 +248,15 @@ mod tests {
assert_eq!(dec.exponent, 0) assert_eq!(dec.exponent, 0)
} }
#[test]
fn float_to_decimal_ten() {
let dec = Decimal::<5>::try_from(10.0).unwrap();
assert!(!dec.minus);
assert_eq!(dec.significant, [1, 0, 0, 0, 0]);
assert!(!dec.minus_exponent);
assert_eq!(dec.exponent, 1)
}
#[test] #[test]
fn float_to_decimal_pos_big() { fn float_to_decimal_pos_big() {
let dec = Decimal::<7>::try_from(1337.42).unwrap(); let dec = Decimal::<7>::try_from(1337.42).unwrap();
@@ -344,7 +358,10 @@ mod tests {
dec.significant = [1, 3, 3, 7, 4, 2, 1]; dec.significant = [1, 3, 3, 7, 4, 2, 1];
dec.minus_exponent = true; dec.minus_exponent = true;
dec.exponent = 2; dec.exponent = 2;
assert_eq!(f64::try_from(dec).unwrap(), 0.01337421); assert_eq!(
round_f(f64::try_from(dec).unwrap(), 8),
round_f(0.01337421, 8)
);
} }
#[test] #[test]
@@ -363,7 +380,10 @@ mod tests {
dec.significant = [1, 3, 3, 7, 4, 2, 1]; dec.significant = [1, 3, 3, 7, 4, 2, 1];
dec.minus_exponent = true; dec.minus_exponent = true;
dec.exponent = 2; dec.exponent = 2;
assert_eq!(f64::try_from(dec).unwrap(), -0.01337421); assert_eq!(
round_f(f64::try_from(dec).unwrap(), 8),
round_f(-0.01337421, 8)
);
} }
#[test] #[test]