fixed_wide_vectors/fixed_wide/src/zeroes.rs

59 lines
1.9 KiB
Rust
Raw Normal View History

2024-09-02 23:15:17 +00:00
use crate::fixed::Fixed;
use crate::ratio::Ratio;
use arrayvec::ArrayVec;
use std::cmp::Ordering;
macro_rules! impl_zeroes{
($n:expr)=>{
2024-09-03 00:03:01 +00:00
impl Fixed<$n,{$n*32}>{
2024-09-02 23:35:01 +00:00
paste::item!{
2024-09-02 23:15:17 +00:00
#[inline]
pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec<Ratio<Self,Self>,2>{
let a2pos=match a2.cmp(&Self::ZERO){
Ordering::Greater=>true,
2024-09-03 00:03:01 +00:00
Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()),
2024-09-02 23:15:17 +00:00
Ordering::Less=>true,
};
2024-09-02 23:35:01 +00:00
let radicand=a1.[<wide_mul_ $n _ $n>](a1)-a2.[<wide_mul_ $n _ $n>](a0)*4;
2024-09-03 00:03:01 +00:00
match radicand.cmp(&Fixed::<{$n*2},{$n*2*32}>::ZERO){
2024-09-02 23:15:17 +00:00
Ordering::Greater=>{
//start with f64 sqrt
//failure case: 2^63 < sqrt(2^127)
2024-09-03 00:03:01 +00:00
let planar_radicand_wide=radicand.sqrt();
//lazy hack
let planar_radicand=Self::from_bits(bnum::cast::As::as_(planar_radicand_wide.bits.shr($n*32)));
2024-09-02 23:15:17 +00:00
//TODO: one or two newtons
//sort roots ascending and avoid taking the difference of large numbers
match (a2pos,Self::ZERO<a1){
(true, true )=>[Ratio::new(-a1-planar_radicand,a2*2),Ratio::new(a0*2,-a1-planar_radicand)].into(),
(true, false)=>[Ratio::new(a0*2,-a1+planar_radicand),Ratio::new(-a1+planar_radicand,a2*2)].into(),
(false,true )=>[Ratio::new(a0*2,-a1-planar_radicand),Ratio::new(-a1-planar_radicand,a2*2)].into(),
(false,false)=>[Ratio::new(-a1+planar_radicand,a2*2),Ratio::new(a0*2,-a1+planar_radicand)].into(),
}
},
Ordering::Equal=>ArrayVec::from_iter([Ratio::new(a1,a2*-2)]),
Ordering::Less=>ArrayVec::new_const(),
}
}
2024-09-02 23:35:01 +00:00
}
2024-09-02 23:15:17 +00:00
#[inline]
pub fn zeroes1(a0:Self,a1:Self)->ArrayVec<Ratio<Self,Self>,1>{
if a1==Self::ZERO{
ArrayVec::new_const()
}else{
ArrayVec::from_iter([Ratio::new(-a0,a1)])
}
}
}
};
}
impl_zeroes!(1);
impl_zeroes!(2);
impl_zeroes!(3);
impl_zeroes!(4);
2024-09-03 00:03:01 +00:00
//sqrt doubles twice!
//impl_zeroes!(5);
//impl_zeroes!(6);
//impl_zeroes!(7);
//impl_zeroes!(8);