use generics for float operations

This commit is contained in:
2025-07-18 21:19:30 +01:00
parent cfee5d2214
commit cd6f9486f7
2 changed files with 133 additions and 101 deletions

View File

@@ -1,6 +1,6 @@
use core::{convert::Infallible, fmt::Display};
use core::{convert::Infallible, fmt::Display, marker::PhantomData};
use num_traits::{PrimInt, Unsigned};
use num_traits::{float::FloatCore, PrimInt, Unsigned};
use crate::{Decimal, DecimalError};
@@ -22,16 +22,20 @@ impl Display for StackCalcError {
}
#[derive(Debug, Clone)]
pub struct StackCalc<const SS: usize = 2, const DS: usize = 5, E = u16> {
stack: [Decimal<DS, E>; SS],
pub struct StackCalc<F: FloatCore, const STACK: usize = 2, const DSIZE: usize = 5, EXP = u16> {
stack: [Decimal<DSIZE, EXP>; STACK],
index: usize,
phantom: PhantomData<F>,
}
impl<const SS: usize, const DS: usize, E: PrimInt> Default for StackCalc<SS, DS, E> {
impl<F: FloatCore, const STACK: usize, const DSIZE: usize, EXP: PrimInt> Default
for StackCalc<F, STACK, DSIZE, EXP>
{
fn default() -> Self {
StackCalc {
stack: [Decimal::default(); SS],
stack: [Decimal::default(); STACK],
index: 0,
phantom: PhantomData,
}
}
}
@@ -48,12 +52,14 @@ impl From<Infallible> for StackCalcError {
}
}
impl<const SS: usize, const DS: usize, E: PrimInt + Unsigned> StackCalc<SS, DS, E> {
impl<F: FloatCore, const STACK: usize, const DSIZE: usize, EXP: PrimInt + Unsigned>
StackCalc<F, STACK, DSIZE, EXP>
{
pub fn push(
&mut self,
val: impl TryInto<Decimal<DS, E>, Error: Into<StackCalcError>>,
val: impl TryInto<Decimal<DSIZE, EXP>, Error: Into<StackCalcError>>,
) -> Result<(), StackCalcError> {
if self.index == SS {
if self.index == STACK {
return Err(StackCalcError::StackOverflow);
}
self.stack[self.index] = val.try_into().map_err(Into::into)?;
@@ -61,7 +67,7 @@ impl<const SS: usize, const DS: usize, E: PrimInt + Unsigned> StackCalc<SS, DS,
Ok(())
}
pub fn pop(&mut self) -> Result<Decimal<DS, E>, StackCalcError> {
pub fn pop(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
if self.index == 0 {
return Err(StackCalcError::StackUnderflow);
}
@@ -69,12 +75,12 @@ impl<const SS: usize, const DS: usize, E: PrimInt + Unsigned> StackCalc<SS, DS,
Ok(self.stack[self.index])
}
pub fn add(&mut self) -> Result<Decimal<DS, E>, StackCalcError> {
pub fn add(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
let a = self.pop()?;
let b = self.pop()?;
let a = f32::try_from(a)?;
let b = f32::try_from(b)?;
let res = Decimal::try_from(a + b)?;
let a = a.to_float::<F>()?;
let b = b.to_float::<F>()?;
let res = Decimal::from_float(a + b)?;
self.push(res)?;
Ok(res)
}
@@ -85,7 +91,7 @@ mod tests {
use super::*;
#[test]
fn test_add() -> Result<(), StackCalcError> {
let mut calc = StackCalc::<3, 7>::default();
let mut calc = StackCalc::<f64, 3, 7>::default();
calc.push(Decimal::default())?;
calc.push(1337.42)?;
assert_eq!(calc.add()?, Decimal::try_from(1337.42)?);