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 = [
|
||||
"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"
|
||||
|
@ -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"
|
||||
|
@ -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")
|
||||
|
@ -1,6 +1,5 @@
|
||||
pub mod fixed;
|
||||
pub mod types;
|
||||
pub mod traits;
|
||||
|
||||
pub mod typenum{
|
||||
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 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{
|
||||
|
Loading…
Reference in New Issue
Block a user