fixed_wide_vectors/fixed_wide/src/wide.rs
2024-08-23 17:23:21 -07:00

63 lines
1.4 KiB
Rust

use bnum::cast::As;
use bnum::types::{I256,I512};
use fixed::FixedI128;
use typenum::{Sum,Unsigned};
#[derive(Clone,Copy,Debug)]
pub struct Fixed<Int,Frac>{
bits:Int,
phantom:std::marker::PhantomData<Frac>,
}
pub type FixedI256<Frac>=Fixed<I256,Frac>;
pub type FixedI512<Frac>=Fixed<I512,Frac>;
impl<Int:From<i128>+std::ops::Shl<u32,Output=Int>,FracDst:Unsigned> From<i128> for Fixed<Int,FracDst>{
fn from(value:i128)->Self{
Self{
bits:Int::from(value)<<FracDst::U32,
phantom:std::marker::PhantomData,
}
}
}
impl<Int:PartialEq,Frac> PartialEq for Fixed<Int,Frac>{
fn eq(&self,other:&Self)->bool{
self.bits==other.bits
}
}
impl<Int:Eq,Frac> Eq for Fixed<Int,Frac>{}
pub trait WideMul<Rhs=Self>{
type Output;
fn wide_mul(self,rhs:Rhs)->Self::Output;
}
//going wide from foreign fixed type
impl<A,B> WideMul<FixedI128<B>> for FixedI128<A>
where
A:std::ops::Add<B>,
B:Unsigned,
{
type Output=FixedI256<Sum<A,B>>;
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,
}
}
}
//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,
}
}
}