diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 7abb1fc..83125b3 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,4 +1,4 @@ -use bnum::BInt; +use bnum::{BInt,cast::As}; use typenum::Unsigned; use std::marker::PhantomData; @@ -60,7 +60,7 @@ impl std::ops::Neg for Fixed{ } } -macro_rules! impl_operator { +macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct{ type Output = $output; @@ -87,7 +87,7 @@ macro_rules! impl_operator { } }; } -macro_rules! impl_assign_operator { +macro_rules! impl_additive_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { impl core::ops::$trait for $struct{ fn $method(&mut self, other: Self) { @@ -106,24 +106,155 @@ macro_rules! impl_assign_operator { } // Impl arithmetic pperators -impl_assign_operator!( Fixed, AddAssign, add_assign ); -impl_operator!( Fixed, Add, add, Self ); -impl_assign_operator!( Fixed, SubAssign, sub_assign ); -impl_operator!( Fixed, Sub, sub, Self ); -impl_assign_operator!( Fixed, MulAssign, mul_assign ); -impl_operator!( Fixed, Mul, mul, Self ); -impl_assign_operator!( Fixed, DivAssign, div_assign ); -impl_operator!( Fixed, Div, div, Self ); -impl_assign_operator!( Fixed, RemAssign, rem_assign ); -impl_operator!( Fixed, Rem, rem, Self ); +impl_additive_assign_operator!( Fixed, AddAssign, add_assign ); +impl_additive_operator!( Fixed, Add, add, Self ); +impl_additive_assign_operator!( Fixed, SubAssign, sub_assign ); +impl_additive_operator!( Fixed, Sub, sub, Self ); +impl_additive_assign_operator!( Fixed, RemAssign, rem_assign ); +impl_additive_operator!( Fixed, Rem, rem, Self ); // Impl bitwise operators -impl_assign_operator!( Fixed, BitAndAssign, bitand_assign ); -impl_operator!( Fixed, BitAnd, bitand, Self ); -impl_assign_operator!( Fixed, BitOrAssign, bitor_assign ); -impl_operator!( Fixed, BitOr, bitor, Self ); -impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); -impl_operator!( Fixed, BitXor, bitxor, Self ); +impl_additive_assign_operator!( Fixed, BitAndAssign, bitand_assign ); +impl_additive_operator!( Fixed, BitAnd, bitand, Self ); +impl_additive_assign_operator!( Fixed, BitOrAssign, bitor_assign ); +impl_additive_operator!( Fixed, BitOr, bitor, Self ); +impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); +impl_additive_operator!( Fixed, BitXor, bitxor, Self ); + +macro_rules! impl_multiply_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + //this can be done better but that is a job for later + let lhs=self.bits.as_::>(); + let rhs=other.bits.as_::>(); + Self { + bits:lhs.mul(rhs).shr(Frac::U32).as_(), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_multiply_assign_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); + } + } + }; +} + +macro_rules! impl_divide_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + //this can be done better but that is a job for later + //this only needs to be $width+Frac::U32/64+1 but MUH CONST GENERICS!!!!! + let lhs=self.bits.as_::>().shl(Frac::U32); + let rhs=other.bits.as_::>(); + Self { + bits:lhs.div(rhs).as_(), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_divide_assign_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); + } + } + }; +} + +macro_rules! impl_multiplicatave_operator { + ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct + where + BInt:::From+core::ops::$trait, + { + type Output = $output; + + fn $method(self, other: U) -> Self::Output { + Self { + bits:self.bits.$method(BInt::::from(other)), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_multiplicatave_assign_operator { + ( $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct + where + BInt:::From+core::ops::$trait, + { + fn $method(&mut self, other: U) { + self.bits.$method(BInt::::from(other)); + } + } + }; +} + +macro_rules! impl_operator_16 { + ( $macro: ident, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + $macro!(1,$struct,$trait,$method,$output); + $macro!(2,$struct,$trait,$method,$output); + $macro!(3,$struct,$trait,$method,$output); + $macro!(4,$struct,$trait,$method,$output); + $macro!(5,$struct,$trait,$method,$output); + $macro!(6,$struct,$trait,$method,$output); + $macro!(7,$struct,$trait,$method,$output); + $macro!(8,$struct,$trait,$method,$output); + $macro!(9,$struct,$trait,$method,$output); + $macro!(10,$struct,$trait,$method,$output); + $macro!(11,$struct,$trait,$method,$output); + $macro!(12,$struct,$trait,$method,$output); + $macro!(13,$struct,$trait,$method,$output); + $macro!(14,$struct,$trait,$method,$output); + $macro!(15,$struct,$trait,$method,$output); + $macro!(16,$struct,$trait,$method,$output); + } +} +macro_rules! impl_assign_operator_16 { + ( $macro: ident, $struct: ident, $trait: ident, $method: ident ) => { + $macro!(1,$struct,$trait,$method); + $macro!(2,$struct,$trait,$method); + $macro!(3,$struct,$trait,$method); + $macro!(4,$struct,$trait,$method); + $macro!(5,$struct,$trait,$method); + $macro!(6,$struct,$trait,$method); + $macro!(7,$struct,$trait,$method); + $macro!(8,$struct,$trait,$method); + $macro!(9,$struct,$trait,$method); + $macro!(10,$struct,$trait,$method); + $macro!(11,$struct,$trait,$method); + $macro!(12,$struct,$trait,$method); + $macro!(13,$struct,$trait,$method); + $macro!(14,$struct,$trait,$method); + $macro!(15,$struct,$trait,$method); + $macro!(16,$struct,$trait,$method); + } +} + +impl_assign_operator_16!( impl_multiply_assign_operator_const, Fixed, MulAssign, mul_assign ); +impl_operator_16!( impl_multiply_operator_const, Fixed, Mul, mul, Self ); +impl_assign_operator_16!( impl_divide_assign_operator_const, Fixed, DivAssign, div_assign ); +impl_operator_16!( impl_divide_operator_const, Fixed, Div, div, Self ); +impl_multiplicatave_assign_operator!( Fixed, MulAssign, mul_assign ); +impl_multiplicatave_operator!( Fixed, Mul, mul, Self ); +impl_multiplicatave_assign_operator!( Fixed, DivAssign, div_assign ); +impl_multiplicatave_operator!( Fixed, Div, div, Self ); macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { @@ -153,7 +284,10 @@ impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); -impl Fixed{ +impl Fixed + where + Fixed:::std::ops::Mul,Output=Fixed>, +{ pub fn sqrt_unchecked(self)->Self{ //find pow2 more powerful than self let mut pow2=if Self::ONE