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 = [
"arrayvec",
"bnum",
"paste",
"typenum",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "typenum"
version = "1.17.0"

View File

@ -12,3 +12,4 @@ zeroes=["ratio","dep:arrayvec"]
bnum = "0.11.0"
typenum = "1.17.0"
arrayvec = { version = "0.7.6", optional = true }
paste = "1.0.15"

View File

@ -1,6 +1,5 @@
use bnum::{BInt,cast::As};
use typenum::{Sum,Unsigned};
use crate::traits::WideMul;
#[derive(Clone,Copy,Debug,Hash)]
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);
macro_rules! impl_wide_mul{
($lhs:expr,$rhs:expr)=>{
impl<A,B> WideMul<Fixed<$rhs,B>> for Fixed<$lhs,A>
where
A:std::ops::Add<B>,
B:Unsigned,
impl<A> Fixed<$lhs,A>
{
type Output=Fixed<{$lhs+$rhs},Sum<A,B>>;
fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{
Fixed::from_bits(self.bits.as_::<BInt<{$lhs+$rhs}>>()*rhs.bits.as_::<BInt<{$lhs+$rhs}>>())
paste::item!{
pub fn [<wide_mul_ $lhs _ $rhs>]<B>(self,rhs:Fixed<$rhs,B>)->Fixed<{$lhs+$rhs},Sum<A,B>>
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{
($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{
//1<<max_shift must be the minimum power of two which when squared is greater than self
//calculating max_shift:
@ -337,16 +338,17 @@ macro_rules! impl_const{
let mut result=Self::ZERO;
//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
for shift in (0..=max_shift).rev(){
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
}
}
pub fn sqrt(self)->Self{
if self<Self::ZERO{
panic!("Square root less than zero")

View File

@ -1,6 +1,5 @@
pub mod fixed;
pub mod types;
pub mod traits;
pub mod typenum{
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 as std::ops::Add>::Output:Unsigned,
{
paste::item!{
#[inline]
pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec<Ratio<Self,Self>,2>{
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::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){
Ordering::Greater=>{
//start with f64 sqrt
@ -37,6 +38,7 @@ macro_rules! impl_zeroes{
Ordering::Less=>ArrayVec::new_const(),
}
}
}
#[inline]
pub fn zeroes1(a0:Self,a1:Self)->ArrayVec<Ratio<Self,Self>,1>{
if a1==Self::ZERO{