cleanup and from_float refactoring

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

View File

@@ -188,7 +188,7 @@ mod tests {
#[test] #[test]
fn test_add_10() -> Result<(), StackCalcError> { fn test_add_10() -> Result<(), StackCalcError> {
let mut calc = StackCalc::<f64, 3, 5>::default(); let mut calc = StackCalc::<f32, 3, 5>::default();
calc.push(Decimal::new(false, [3, 0, 0, 0, 0], false, 0))?; calc.push(Decimal::new(false, [3, 0, 0, 0, 0], false, 0))?;
calc.push(Decimal::new(false, [7, 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)); assert_eq!(calc.add()?, Decimal::new(false, [1, 0, 0, 0, 0], false, 1));

View File

@@ -75,37 +75,37 @@ impl<const SIZE: usize, EXP: PrimInt + Unsigned> Decimal<SIZE, EXP> {
if !f.is_finite() { if !f.is_finite() {
return Err(DecimalError::NotANumber); return Err(DecimalError::NotANumber);
} }
let minus = f.is_sign_negative(); let minus = f.is_sign_negative();
if minus { if minus {
f = f * F::from(-1).unwrap(); f = f * F::from(-1).unwrap();
} }
let mut significant = [0; SIZE];
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() { let ten = F::from(10).unwrap();
f = f / F::from(10).unwrap();
exponent = exponent if !f.is_zero() {
.checked_add(&one()) while f >= ten {
.ok_or(DecimalError::ExponentOverflow)?; f = f / ten;
} exponent = exponent
while f < one() { .checked_add(&one())
if f == f * F::from(10).unwrap() { .ok_or(DecimalError::ExponentOverflow)?;
break; }
while f < one() {
f = f * ten;
exponent = exponent
.checked_add(&one())
.ok_or(DecimalError::ExponentOverflow)?;
} }
f = f * F::from(10).unwrap();
exponent = exponent
.checked_add(&one())
.ok_or(DecimalError::ExponentOverflow)?;
} }
let mut significant = [0; SIZE];
for i in 0..SIZE { for i in 0..SIZE {
let mut s = f.trunc().to_u8().unwrap(); significant[i] = f.trunc().to_u8().unwrap();
if s >= 10 { f = f.fract() * ten;
s = 9;
}
f = f * F::from(10).unwrap();
f = f - F::from(s * 10).ok_or(DecimalError::ExponentOverflow)?;
significant[i] = s;
} }
Ok(Decimal { Ok(Decimal {
minus, minus,
significant, significant,
@@ -249,7 +249,7 @@ mod tests {
} }
#[test] #[test]
fn float_to_decimal_ten() { fn float_to_decimal_10() {
let dec = Decimal::<5>::try_from(10.0).unwrap(); let dec = Decimal::<5>::try_from(10.0).unwrap();
assert!(!dec.minus); assert!(!dec.minus);
assert_eq!(dec.significant, [1, 0, 0, 0, 0]); assert_eq!(dec.significant, [1, 0, 0, 0, 0]);
@@ -257,6 +257,16 @@ mod tests {
assert_eq!(dec.exponent, 1) assert_eq!(dec.exponent, 1)
} }
#[test]
#[ignore = "dbg![1.14f32.fract()]; // 0.13999999"]
fn float_to_decimal_114() {
let dec = Decimal::<5>::try_from(114.0f32).unwrap();
assert!(!dec.minus);
assert_eq!(dec.significant, [1, 1, 4, 0, 0]);
assert!(!dec.minus_exponent);
assert_eq!(dec.exponent, 2)
}
#[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();