fixed_wide_vectors/fixed_wide/src/wide.rs

73 lines
1.6 KiB
Rust
Raw Normal View History

2024-08-23 21:17:48 +00:00
use bnum::cast::As;
2024-08-23 20:42:44 +00:00
use bnum::types::{I256,I512};
2024-08-23 23:26:19 +00:00
use fixed::{FixedI64,FixedI128};
2024-08-23 22:45:01 +00:00
use typenum::{Sum,Unsigned};
2024-08-23 20:42:44 +00:00
2024-08-23 21:17:48 +00:00
#[derive(Clone,Copy,Debug)]
2024-08-23 20:42:44 +00:00
pub struct Fixed<Int,Frac>{
bits:Int,
2024-08-23 20:00:22 +00:00
phantom:std::marker::PhantomData<Frac>,
}
2024-08-23 20:42:44 +00:00
pub type FixedI256<Frac>=Fixed<I256,Frac>;
pub type FixedI512<Frac>=Fixed<I512,Frac>;
2024-08-23 21:17:48 +00:00
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
2024-08-23 23:26:19 +00:00
impl<A,B> WideMul<FixedI64<B>> for FixedI64<A>
where
A:std::ops::Add<B>,
B:Unsigned,
{
type Output=FixedI128<Sum<A,B>>;
fn wide_mul(self,rhs:FixedI64<B>)->Self::Output{
self.wide_mul(rhs)
}
}
2024-08-23 20:42:44 +00:00
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,
}
}
}
2024-08-23 21:17:48 +00:00
//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,
}
}
}