This commit is contained in:
Quaternions 2024-08-23 14:17:48 -07:00
parent 276602e5f3
commit 5f8104d531
4 changed files with 75 additions and 24 deletions

View File

@ -1 +1,2 @@
pub mod wide;
pub mod types;

2
fixed_wide/src/types.rs Normal file
View File

@ -0,0 +1,2 @@
pub type I256F128=crate::wide::FixedI256<typenum::consts::U128>;
pub type I512F256=crate::wide::FixedI512<typenum::consts::U256>;

View File

@ -1,13 +1,10 @@
use bnum::cast::As;
use bnum::types::{I256,I512};
use fixed::{FixedI64,FixedI128};
use typenum::{Sum, Unsigned};
use typenum::consts::{U32,U64,U96,U128,U160,U192,U224,U256};
pub trait WideMul<Rhs=Self>{
type Output;
fn wide_mul(self,rhs:Rhs)->Self::Output;
}
#[derive(Clone,Copy,Debug)]
pub struct Fixed<Int,Frac>{
bits:Int,
phantom:std::marker::PhantomData<Frac>,
@ -15,6 +12,28 @@ pub struct Fixed<Int,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>,
@ -28,3 +47,40 @@ impl<A,B> WideMul<FixedI128<B>> for FixedI128<A>
}
}
}
//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,
}
}
}
pub enum Narrower<T>{
Fits(T),
Max,
Min,
}
fn tat(){
let a:i8=match 257i64.try_into() {
Ok(it) => it,
Err(err) => panic!(),
};
}
//i16 -> i8
// 257i16.try_narrow::<i8>() -> Narrower::Max
// 128i16.try_narrow::<i8>() -> Narrower::Fits(128i8)
// -257i16.try_narrow::<i8>() -> Narrower::Min
pub trait TryNarrow<Rhs=Self>{
type Output;
fn wide_mul(self,rhs:Rhs)->Self::Output;
}

View File

@ -1,22 +1,9 @@
use bnum::cast::As;
use fixed_wide::wide::WideMul;
type Planar64=fixed::types::I32F32;
type Planar64Wide1=fixed::types::I64F64;
type Planar64Wide2=bnum::types::I256;
type Planar64Wide3=bnum::types::I512;
//wouldn't that be nice
//type Planar64Wide2=fixed::FixedI256<fixed::types::extra::U128>;
//type Planar64Wide3=fixed::FixedI512<fixed::types::extra::U256>;
pub fn wide_mul(left: Planar64, right: Planar64) -> Planar64Wide1 {
left.wide_mul(right)
}
pub fn wide_mul_2(left: Planar64Wide1, right: Planar64Wide1) -> Planar64Wide2 {
Planar64Wide2::from(left.to_bits())*Planar64Wide2::from(right.to_bits())
}
pub fn wide_mul_3(left: Planar64Wide2, right: Planar64Wide2) -> Planar64Wide3 {
left.as_::<Planar64Wide3>()*right.as_::<Planar64Wide3>()
}
type Planar64Wide2=fixed_wide::types::I256F128;
type Planar64Wide3=fixed_wide::types::I512F256;
#[cfg(test)]
mod tests {
@ -24,13 +11,18 @@ mod tests {
#[test]
fn it_works() {
let result = add(2.into(), 2.into());
assert_eq!(result, 4);
let a=Planar64::from(2);
let b=Planar64::from(3);
let w1=a.wide_mul(b);
let w2=w1.wide_mul(w1);
let w3=w2.wide_mul(w2);
assert_eq!(w3,Planar64Wide3::from(1296));
}
#[test]
pub fn main(){
let a=6f128;
let max=i32::MAX as i64;
println!("{} {}",max*max,i64::MAX);
}