further sqrt improvements
This commit is contained in:
parent
e684fb421e
commit
6ea9eff844
@ -18,6 +18,15 @@ impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>{
|
|||||||
pub const NEG_ONE:Self=Self{bits:BInt::<CHUNKS>::NEG_ONE.shl(Frac::U32),frac:PhantomData};
|
pub const NEG_ONE:Self=Self{bits:BInt::<CHUNKS>::NEG_ONE.shl(Frac::U32),frac:PhantomData};
|
||||||
pub const NEG_TWO:Self=Self{bits:BInt::<CHUNKS>::NEG_TWO.shl(Frac::U32),frac:PhantomData};
|
pub const NEG_TWO:Self=Self{bits:BInt::<CHUNKS>::NEG_TWO.shl(Frac::U32),frac:PhantomData};
|
||||||
pub const NEG_HALF:Self=Self{bits:BInt::<CHUNKS>::NEG_ONE.shl(Frac::U32-1),frac:PhantomData};
|
pub const NEG_HALF:Self=Self{bits:BInt::<CHUNKS>::NEG_ONE.shl(Frac::U32-1),frac:PhantomData};
|
||||||
|
pub const fn from_bits(bits:BInt::<CHUNKS>)->Self{
|
||||||
|
Self{
|
||||||
|
bits,
|
||||||
|
frac:PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub const fn to_bits(self)->BInt<CHUNKS>{
|
||||||
|
self.bits
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const CHUNKS:usize,Frac:Unsigned,T> From<T> for Fixed<CHUNKS,Frac>
|
impl<const CHUNKS:usize,Frac:Unsigned,T> From<T> for Fixed<CHUNKS,Frac>
|
||||||
@ -290,6 +299,13 @@ impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>
|
|||||||
{
|
{
|
||||||
pub fn sqrt_unchecked(self)->Self{
|
pub fn sqrt_unchecked(self)->Self{
|
||||||
//pow2 must be the minimum power of two which when squared is greater than 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
|
||||||
|
//Voila
|
||||||
//0001.0000 Fixed<u8,4>
|
//0001.0000 Fixed<u8,4>
|
||||||
//sqrt
|
//sqrt
|
||||||
//0110.0000
|
//0110.0000
|
||||||
@ -300,14 +316,21 @@ impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>
|
|||||||
};
|
};
|
||||||
let mut result=pow2>>1;
|
let mut result=pow2>>1;
|
||||||
|
|
||||||
while pow2!=Self::ZERO{
|
loop{
|
||||||
pow2>>=1;
|
pow2>>=1;
|
||||||
|
if pow2==Self::ZERO{
|
||||||
|
break result;
|
||||||
|
}
|
||||||
|
//TODO: flip a single bit instead of adding a power of 2
|
||||||
let new_result=result+pow2;
|
let new_result=result+pow2;
|
||||||
if new_result*new_result<=self{
|
//note that the implicit truncation in the multiply
|
||||||
result=new_result;
|
//means that the algorithm can return a result which squares to a number greater than the input.
|
||||||
|
match self.cmp(&(new_result*new_result)){
|
||||||
|
core::cmp::Ordering::Less=>continue,
|
||||||
|
core::cmp::Ordering::Equal=>break new_result,
|
||||||
|
core::cmp::Ordering::Greater=>result=new_result,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
pub fn sqrt(self)->Self{
|
pub fn sqrt(self)->Self{
|
||||||
if self<Self::ZERO{
|
if self<Self::ZERO{
|
||||||
|
Loading…
Reference in New Issue
Block a user