paste (this sucks)
This commit is contained in:
parent
2a2e729f59
commit
4d13b4ada7
7
fixed_wide/Cargo.lock
generated
7
fixed_wide/Cargo.lock
generated
@ -20,9 +20,16 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bnum",
|
"bnum",
|
||||||
|
"paste",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
|
@ -12,3 +12,4 @@ zeroes=["ratio","dep:arrayvec"]
|
|||||||
bnum = "0.11.0"
|
bnum = "0.11.0"
|
||||||
typenum = "1.17.0"
|
typenum = "1.17.0"
|
||||||
arrayvec = { version = "0.7.6", optional = true }
|
arrayvec = { version = "0.7.6", optional = true }
|
||||||
|
paste = "1.0.15"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use bnum::{BInt,cast::As};
|
use bnum::{BInt,cast::As};
|
||||||
use typenum::{Sum,Unsigned};
|
use typenum::{Sum,Unsigned};
|
||||||
use crate::traits::WideMul;
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash)]
|
#[derive(Clone,Copy,Debug,Hash)]
|
||||||
pub struct Fixed<const CHUNKS:usize,Frac>{
|
pub struct Fixed<const CHUNKS:usize,Frac>{
|
||||||
@ -284,14 +283,15 @@ impl_shift_operator!( Fixed, Shr, shr, Self );
|
|||||||
// let b:I64F64 = a.wide_mul(a);
|
// let b:I64F64 = a.wide_mul(a);
|
||||||
macro_rules! impl_wide_mul{
|
macro_rules! impl_wide_mul{
|
||||||
($lhs:expr,$rhs:expr)=>{
|
($lhs:expr,$rhs:expr)=>{
|
||||||
impl<A,B> WideMul<Fixed<$rhs,B>> for Fixed<$lhs,A>
|
impl<A> Fixed<$lhs,A>
|
||||||
where
|
|
||||||
A:std::ops::Add<B>,
|
|
||||||
B:Unsigned,
|
|
||||||
{
|
{
|
||||||
type Output=Fixed<{$lhs+$rhs},Sum<A,B>>;
|
paste::item!{
|
||||||
fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{
|
pub fn [<wide_mul_ $lhs _ $rhs>]<B>(self,rhs:Fixed<$rhs,B>)->Fixed<{$lhs+$rhs},Sum<A,B>>
|
||||||
Fixed::from_bits(self.bits.as_::<BInt<{$lhs+$rhs}>>()*rhs.bits.as_::<BInt<{$lhs+$rhs}>>())
|
where
|
||||||
|
A:std::ops::Add<B>,
|
||||||
|
B:Unsigned,{
|
||||||
|
Fixed::from_bits(self.bits.as_::<BInt<{$lhs+$rhs}>>()*rhs.bits.as_::<BInt<{$lhs+$rhs}>>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -324,7 +324,8 @@ impl<const SRC:usize,Frac> Fixed<SRC,Frac>{
|
|||||||
|
|
||||||
macro_rules! impl_const{
|
macro_rules! impl_const{
|
||||||
($n:expr)=>{
|
($n:expr)=>{
|
||||||
impl<F:Unsigned> Fixed<$n,F>{
|
impl<F:Unsigned+std::ops::Add> Fixed<$n,F>{
|
||||||
|
paste::item!{
|
||||||
pub fn sqrt_unchecked(self)->Self{
|
pub fn sqrt_unchecked(self)->Self{
|
||||||
//1<<max_shift must be the minimum power of two which when squared is greater than self
|
//1<<max_shift must be the minimum power of two which when squared is greater than self
|
||||||
//calculating max_shift:
|
//calculating max_shift:
|
||||||
@ -337,16 +338,17 @@ macro_rules! impl_const{
|
|||||||
let mut result=Self::ZERO;
|
let mut result=Self::ZERO;
|
||||||
|
|
||||||
//multiply by one to make the types match (hack)
|
//multiply by one to make the types match (hack)
|
||||||
let wide_self=self.wide_mul(Self::ONE);
|
let wide_self=self.[<wide_mul_ $n _ $n>](Self::ONE);
|
||||||
//descend down the bits and check if flipping each bit would push the square over the input value
|
//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(){
|
for shift in (0..=max_shift).rev(){
|
||||||
let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift)));
|
let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift)));
|
||||||
if new_result.wide_mul(new_result)<=wide_self{
|
if new_result.[<wide_mul_ $n _ $n>](new_result)<=wide_self{
|
||||||
result=new_result;
|
result=new_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn sqrt(self)->Self{
|
pub fn sqrt(self)->Self{
|
||||||
if self<Self::ZERO{
|
if self<Self::ZERO{
|
||||||
panic!("Square root less than zero")
|
panic!("Square root less than zero")
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
pub mod fixed;
|
pub mod fixed;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub mod traits;
|
|
||||||
|
|
||||||
pub mod typenum{
|
pub mod typenum{
|
||||||
pub use typenum::Unsigned;
|
pub use typenum::Unsigned;
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
pub trait WideMul<Rhs=Self>{
|
|
||||||
type Output;
|
|
||||||
fn wide_mul(self,rhs:Rhs)->Self::Output;
|
|
||||||
}
|
|
||||||
pub trait WideDiv<Rhs=Self>{
|
|
||||||
type Output;
|
|
||||||
fn wide_div(self,rhs:Rhs)->Self::Output;
|
|
||||||
}
|
|
@ -11,6 +11,7 @@ macro_rules! impl_zeroes{
|
|||||||
F:Unsigned+std::ops::Add,
|
F:Unsigned+std::ops::Add,
|
||||||
<F as std::ops::Add>::Output:Unsigned,
|
<F as std::ops::Add>::Output:Unsigned,
|
||||||
{
|
{
|
||||||
|
paste::item!{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec<Ratio<Self,Self>,2>{
|
pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec<Ratio<Self,Self>,2>{
|
||||||
let a2pos=match a2.cmp(&Self::ZERO){
|
let a2pos=match a2.cmp(&Self::ZERO){
|
||||||
@ -18,7 +19,7 @@ macro_rules! impl_zeroes{
|
|||||||
Ordering::Equal=>return ArrayVec::from_iter($crate::zeroes::zeroes1(a0,a1).into_iter()),
|
Ordering::Equal=>return ArrayVec::from_iter($crate::zeroes::zeroes1(a0,a1).into_iter()),
|
||||||
Ordering::Less=>true,
|
Ordering::Less=>true,
|
||||||
};
|
};
|
||||||
let radicand=$crate::traits::WideMul::wide_mul(a1,a1)-$crate::traits::WideMul::wide_mul(a2,a0)*4;
|
let radicand=a1.[<wide_mul_ $n _ $n>](a1)-a2.[<wide_mul_ $n _ $n>](a0)*4;
|
||||||
match radicand.cmp(&Fixed::<{$n*2},Sum<F,F>>::ZERO){
|
match radicand.cmp(&Fixed::<{$n*2},Sum<F,F>>::ZERO){
|
||||||
Ordering::Greater=>{
|
Ordering::Greater=>{
|
||||||
//start with f64 sqrt
|
//start with f64 sqrt
|
||||||
@ -37,6 +38,7 @@ macro_rules! impl_zeroes{
|
|||||||
Ordering::Less=>ArrayVec::new_const(),
|
Ordering::Less=>ArrayVec::new_const(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zeroes1(a0:Self,a1:Self)->ArrayVec<Ratio<Self,Self>,1>{
|
pub fn zeroes1(a0:Self,a1:Self)->ArrayVec<Ratio<Self,Self>,1>{
|
||||||
if a1==Self::ZERO{
|
if a1==Self::ZERO{
|
||||||
|
Loading…
Reference in New Issue
Block a user