describe algorithm
This commit is contained in:
parent
70a79a8d25
commit
3c5f01da89
@ -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{
|
||||
|
Loading…
Reference in New Issue
Block a user