paste (this sucks)

This commit is contained in:
Quaternions 2024-09-02 16:35:01 -07:00
parent 2a2e729f59
commit 4d13b4ada7
6 changed files with 24 additions and 21 deletions

7
fixed_wide/Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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")

View File

@ -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;

View File

@ -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;
}

View File

@ -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{