From 3c5f01da89995983442c893565fc553178d9b431 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 18:38:18 -0700 Subject: [PATCH] describe algorithm --- fixed_wide/src/fixed_wide_traits.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index bd9ac24..b2b41de 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -57,24 +57,19 @@ impl Fixed as WideMul>::Output:Ord, { pub fn sqrt_unchecked(self)->Self{ - //pow2 must be the minimum power of two which when squared is greater than self - //the algorithm: - //1. count "used" bits to the left of the decimal - //2. add one - //This is the power of two which is greater than self. - //3. divide by 2 via >>1 - //4. add on fractional offset + //1<>1 (sqrt-ish) + //3. add on fractional offset //Voila - //0001.0000 Fixed - //sqrt - //0110.0000 - //pow2 = 0100.0000 let used_bits=CHUNKS as i32*64-1-Frac::I32-self.bits.leading_zeros() as i32; let max_shift=((used_bits>>1)+Frac::I32) as u32; let mut result=Self::ZERO; - //cheat to make the types match + //multiply by one to make the types match (hack) let wide_self=self.wide_mul(Fixed::::ONE); + //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ let new_result=result|Fixed::::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); if new_result.wide_mul(new_result)<=wide_self{