describe algorithm

This commit is contained in:
Quaternions 2024-08-29 18:38:18 -07:00
parent 70a79a8d25
commit 3c5f01da89

View File

@ -57,24 +57,19 @@ impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>
<Fixed::<CHUNKS,Frac> 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<<max_shift must be the minimum power of two which when squared is greater than self
//calculating max_shift:
//1. count "used" bits to the left of the decimal, not including the sign bit (so -1)
//2. divide by 2 via >>1 (sqrt-ish)
//3. add on fractional offset
//Voila
//0001.0000 Fixed<u8,4>
//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::<CHUNKS,Frac>::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::<CHUNKS,Frac>::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift)));
if new_result.wide_mul(new_result)<=wide_self{