diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 9d050cea9..114c67398 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,38 +1,41 @@ use bnum::cast::As; use bnum::types::{I256,I512}; +use bnum::BInt; use fixed::{FixedI64,FixedI128}; use typenum::{Sum,Unsigned}; +use std::marker::PhantomData; #[derive(Clone,Copy,Debug)] -pub struct Fixed<Int,Frac>{ - bits:Int, - phantom:std::marker::PhantomData<Frac>, +pub struct Fixed<const CHUNKS:usize,Frac>{ + bits:BInt<{CHUNKS}>, + frac:PhantomData<Frac>, } -pub type FixedI256<Frac>=Fixed<I256,Frac>; -pub type FixedI512<Frac>=Fixed<I512,Frac>; +pub type FixedI192<Frac>=Fixed<3,Frac>; +pub type FixedI256<Frac>=Fixed<4,Frac>; +pub type FixedI512<Frac>=Fixed<8,Frac>; -impl<Int:From<i128>+std::ops::Shl<u32,Output=Int>,FracDst:Unsigned> From<i128> for Fixed<Int,FracDst>{ +impl<const CHUNKS:usize,FracDst:Unsigned> From<i128> for Fixed<CHUNKS,FracDst>{ fn from(value:i128)->Self{ Self{ - bits:Int::from(value)<<FracDst::U32, - phantom:std::marker::PhantomData, + bits:BInt::<{CHUNKS}>::from(value)<<FracDst::U32, + frac:PhantomData, } } } -impl<Int:PartialEq,Frac> PartialEq for Fixed<Int,Frac>{ +impl<const CHUNKS:usize,Frac> PartialEq for Fixed<CHUNKS,Frac>{ fn eq(&self,other:&Self)->bool{ self.bits.eq(&other.bits) } } -impl<Int:Eq,Frac> Eq for Fixed<Int,Frac>{} +impl<const CHUNKS:usize,Frac> Eq for Fixed<CHUNKS,Frac>{} -impl<Int:std::ops::Add<Output=Int>,Frac> std::ops::Add for Fixed<Int,Frac>{ +impl<const CHUNKS:usize,Frac> std::ops::Add for Fixed<CHUNKS,Frac>{ type Output=Self; fn add(self,rhs:Self)->Self::Output{ Self{ bits:self.bits+rhs.bits, - phantom:std::marker::PhantomData, + frac:PhantomData, } } } @@ -53,6 +56,32 @@ impl<A,B> WideMul<FixedI64<B>> for FixedI64<A> self.wide_mul(rhs) } } +impl<A,B> WideMul<FixedI64<B>> for FixedI128<A> + where + A:std::ops::Add<B>, + B:Unsigned, +{ + type Output=FixedI192<Sum<A,B>>; + fn wide_mul(self,rhs:FixedI64<B>)->Self::Output{ + FixedI192{ + bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), + frac:PhantomData, + } + } +} +impl<A,B> WideMul<FixedI128<B>> for FixedI64<A> + where + A:std::ops::Add<B>, + B:Unsigned, +{ + type Output=FixedI192<Sum<A,B>>; + fn wide_mul(self,rhs:FixedI128<B>)->Self::Output{ + FixedI192{ + bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), + frac:PhantomData, + } + } +} impl<A,B> WideMul<FixedI128<B>> for FixedI128<A> where A:std::ops::Add<B>, @@ -62,21 +91,32 @@ impl<A,B> WideMul<FixedI128<B>> for FixedI128<A> fn wide_mul(self,rhs:FixedI128<B>)->Self::Output{ FixedI256{ bits:I256::from(self.to_bits())*I256::from(rhs.to_bits()), - phantom:std::marker::PhantomData, + frac:PhantomData, } } } + //going wider native -impl<A,B> WideMul<FixedI256<B>> for FixedI256<A> - where - A:std::ops::Add<B>, - B:Unsigned, -{ - type Output=FixedI512<Sum<A,B>>; - fn wide_mul(self,rhs:FixedI256<B>)->Self::Output{ - FixedI512{ - bits:self.bits.as_::<I512>()*rhs.bits.as_::<I512>(), - phantom:std::marker::PhantomData, +macro_rules! impl_wide_mul { + ($lhs: expr,$rhs: expr) => { + impl<A,B> WideMul<Fixed<$rhs,B>> for Fixed<$lhs,A> + where + A:std::ops::Add<B>, + B:Unsigned, + { + type Output=Fixed<{$lhs+$rhs},Sum<A,B>>; + fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ + Fixed{ + bits:self.bits.as_::<BInt<{$lhs+$rhs}>>()*rhs.bits.as_::<BInt<{$lhs+$rhs}>>(), + frac:PhantomData, + } + } } - } + }; } +impl_wide_mul!(3,3);impl_wide_mul!(4,3);impl_wide_mul!(5,3);impl_wide_mul!(6,3);impl_wide_mul!(7,3);impl_wide_mul!(8,3); +impl_wide_mul!(3,4);impl_wide_mul!(4,4);impl_wide_mul!(5,4);impl_wide_mul!(6,4);impl_wide_mul!(7,4);impl_wide_mul!(8,4); +impl_wide_mul!(3,5);impl_wide_mul!(4,5);impl_wide_mul!(5,5);impl_wide_mul!(6,5);impl_wide_mul!(7,5);impl_wide_mul!(8,5); +impl_wide_mul!(3,6);impl_wide_mul!(4,6);impl_wide_mul!(5,6);impl_wide_mul!(6,6);impl_wide_mul!(7,6);impl_wide_mul!(8,6); +impl_wide_mul!(3,7);impl_wide_mul!(4,7);impl_wide_mul!(5,7);impl_wide_mul!(6,7);impl_wide_mul!(7,7);impl_wide_mul!(8,7); +impl_wide_mul!(3,8);impl_wide_mul!(4,8);impl_wide_mul!(5,8);impl_wide_mul!(6,8);impl_wide_mul!(7,8);impl_wide_mul!(8,8);