use generics for float operations
This commit is contained in:
36
src/calc.rs
36
src/calc.rs
@@ -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)?);
|
||||
|
||||
Reference in New Issue
Block a user