From 8ee6204a42e8a6a9c4db3a4f166429961678ea24 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 14:45:47 -0700 Subject: [PATCH] invent wide_div + test --- fixed_wide/src/fixed.rs | 17 ++++++++++++++--- fixed_wide/src/tests.rs | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 4cdfdef..c8b1969 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -277,7 +277,7 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // WIDE MUL: multiply into a wider type // let a = I32F32::ONE; // let b:I64F64 = a.wide_mul(a); -macro_rules! impl_wide_mul{ +macro_rules! impl_wide_not_const_generic{ ( (), ($lhs:expr,$rhs:expr) @@ -286,7 +286,18 @@ macro_rules! impl_wide_mul{ { paste::item!{ pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ - Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) + let lhs=self.bits.as_::>(); + let rhs=rhs.bits.as_::>(); + Fixed::from_bits(lhs*rhs) + } + /// This operation cannot represent the fraction exactly, + /// but it shapes the output to have precision for the + /// largest and smallest possible fractions. + pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ + // (lhs/2^LHS_FRAC)/(rhs/2^RHS_FRAC) + let lhs=self.bits.as_::>().shl($rhs*64); + let rhs=rhs.bits.as_::>(); + Fixed::from_bits(lhs/rhs) } } } @@ -295,7 +306,7 @@ macro_rules! impl_wide_mul{ //const generics sidestepped wahoo macro_repeated!( - impl_wide_mul,(), + impl_wide_not_const_generic,(), (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1), (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2), (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3), diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 01fb9f1..43fa2ab 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -20,6 +20,20 @@ fn test_wide_mul(){ assert_eq!(aa,crate::types::I64F64::ONE); } +#[test] +fn test_wide_div(){ + let a=I32F32::ONE*4; + let b=I32F32::ONE*2; + let wide_a=a.wide_mul_1_1(I32F32::ONE); + let wide_b=b.wide_mul_1_1(I32F32::ONE); + let ab=a.wide_div_1_1(b); + assert_eq!(ab,crate::types::I64F64::ONE*2); + let wab=wide_a.wide_div_2_1(b); + assert_eq!(wab,crate::fixed::Fixed::<3,96>::ONE*2); + let awb=a.wide_div_1_2(wide_b); + assert_eq!(awb,crate::fixed::Fixed::<3,96>::ONE*2); +} + #[test] fn test_wide_mul_repeated() { let a=I32F32::from(2);