softposit/
macros.rs

1macro_rules! impl_math_consts {
2    ($T:ty) => {
3        impl $crate::MathConsts for $T {
4            const E: Self = Self::from_f64(core::f64::consts::E);
5            const FRAC_1_PI: Self = Self::from_f64(core::f64::consts::FRAC_1_PI);
6            const FRAC_1_SQRT_2: Self = Self::from_f64(core::f64::consts::FRAC_1_SQRT_2);
7            const FRAC_2_PI: Self = Self::from_f64(core::f64::consts::FRAC_2_PI);
8            const FRAC_2_SQRT_PI: Self = Self::from_f64(core::f64::consts::FRAC_2_SQRT_PI);
9            const FRAC_PI_2: Self = Self::from_f64(core::f64::consts::FRAC_PI_2);
10            const FRAC_PI_3: Self = Self::from_f64(core::f64::consts::FRAC_PI_3);
11            const FRAC_PI_4: Self = Self::from_f64(core::f64::consts::FRAC_PI_4);
12            const FRAC_PI_6: Self = Self::from_f64(core::f64::consts::FRAC_PI_6);
13            const FRAC_PI_8: Self = Self::from_f64(core::f64::consts::FRAC_PI_8);
14            const LN_10: Self = Self::from_f64(core::f64::consts::LN_10);
15            const LN_2: Self = Self::from_f64(core::f64::consts::LN_2);
16            const LOG10_E: Self = Self::from_f64(core::f64::consts::LOG10_E);
17            const LOG2_E: Self = Self::from_f64(core::f64::consts::LOG2_E);
18            const PI: Self = Self::from_f64(core::f64::consts::PI);
19            const SQRT_2: Self = Self::from_f64(core::f64::consts::SQRT_2);
20            const LOG2_10: Self = Self::from_f64(core::f64::consts::LOG2_10);
21            const LOG10_2: Self = Self::from_f64(core::f64::consts::LOG10_2);
22        }
23    };
24}
25pub(crate) use impl_math_consts;
26
27macro_rules! impl_const_fns {
28    ($T:ty) => {
29        impl $T {
30            #[inline]
31            pub const fn abs(self) -> Self {
32                if self.is_sign_negative() {
33                    self.neg()
34                } else {
35                    self
36                }
37            }
38            #[inline]
39            pub const fn is_zero(self) -> bool {
40                self.eq(Self::ZERO)
41            }
42            #[inline]
43            pub const fn is_nar(self) -> bool {
44                self.eq(Self::NAR)
45            }
46            #[inline]
47            pub const fn is_nan(self) -> bool {
48                self.is_nar()
49            }
50            #[inline]
51            pub const fn is_infinite(self) -> bool {
52                self.is_nar()
53            }
54            #[inline]
55            pub const fn is_finite(self) -> bool {
56                !self.is_nar()
57            }
58            #[inline]
59            pub const fn is_normal(self) -> bool {
60                !self.is_nar()
61            }
62            #[inline]
63            pub const fn clamp(mut self, min: Self, max: Self) -> Self {
64                assert!(min.le(max));
65                if self.lt(min) {
66                    self = min;
67                }
68                if self.gt(max) {
69                    self = max;
70                }
71                self
72            }
73            #[inline]
74            pub const fn min(self, other: Self) -> Self {
75                if self.lt(other) {
76                    self
77                } else {
78                    other
79                }
80            }
81            #[inline]
82            pub const fn max(self, other: Self) -> Self {
83                if self.gt(other) {
84                    self
85                } else {
86                    other
87                }
88            }
89            #[inline]
90            pub const fn classify(self) -> core::num::FpCategory {
91                use core::num::FpCategory::*;
92                match self {
93                    Self::ZERO => Zero,
94                    Self::NAR => Nan,
95                    _ => Normal,
96                }
97            }
98            #[inline]
99            pub const fn is_sign_positive(self) -> bool {
100                !self.is_sign_negative()
101            }
102            #[inline]
103            pub const fn is_sign_negative(self) -> bool {
104                self.lt(Self::ZERO)
105            }
106            #[inline]
107            pub const fn signum(self) -> Self {
108                match self.0 {
109                    n if n == Self::NAR.0 => Self::NAR,
110                    n if n > 0 => Self::ONE,
111                    0 => Self::ZERO,
112                    _ => Self::ONE.neg(),
113                }
114            }
115            #[inline]
116            pub const fn copysign(self, other: Self) -> Self {
117                if ((self.to_bits() ^ other.to_bits()) & Self::SIGN_MASK) != 0 {
118                    self.neg()
119                } else {
120                    self
121                }
122            }
123            #[inline]
124            pub const fn eq(self, other: Self) -> bool {
125                self.0 == other.0
126            }
127            #[inline]
128            pub const fn cmp(self, other: Self) -> Ordering {
129                let a = self.0;
130                let b = other.0;
131                if a == b {
132                    Ordering::Equal
133                } else if a < b {
134                    Ordering::Less
135                } else {
136                    Ordering::Greater
137                }
138            }
139            #[inline]
140            pub const fn lt(&self, other: Self) -> bool {
141                self.0 < other.0
142            }
143            #[inline]
144            pub const fn le(&self, other: Self) -> bool {
145                self.0 <= other.0
146            }
147            #[inline]
148            pub const fn ge(&self, other: Self) -> bool {
149                self.0 >= other.0
150            }
151            #[inline]
152            pub const fn gt(&self, other: Self) -> bool {
153                self.0 > other.0
154            }
155        }
156    };
157}
158pub(crate) use impl_const_fns;
159
160macro_rules! impl_ops {
161    ($T:ty) => {
162        impl ops::Neg for $T {
163            type Output = Self;
164            #[inline]
165            fn neg(self) -> Self {
166                self.neg()
167            }
168        }
169
170        impl ops::Add for $T {
171            type Output = Self;
172            #[inline]
173            fn add(self, other: Self) -> Self {
174                self.add(other)
175            }
176        }
177
178        impl ops::Sub for $T {
179            type Output = Self;
180            #[inline]
181            fn sub(self, other: Self) -> Self {
182                self.sub(other)
183            }
184        }
185
186        impl ops::Div for $T {
187            type Output = Self;
188            #[inline]
189            fn div(self, other: Self) -> Self {
190                self.div(other)
191            }
192        }
193
194        impl ops::Mul for $T {
195            type Output = Self;
196            #[inline]
197            fn mul(self, other: Self) -> Self {
198                self.mul(other)
199            }
200        }
201
202        impl ops::Rem for $T {
203            type Output = Self;
204            fn rem(self, other: Self) -> Self {
205                self.rem(other)
206            }
207        }
208
209        impl ops::AddAssign for $T {
210            #[inline]
211            fn add_assign(&mut self, other: Self) {
212                *self = *self + other
213            }
214        }
215
216        impl ops::SubAssign for $T {
217            #[inline]
218            fn sub_assign(&mut self, other: Self) {
219                *self = *self - other
220            }
221        }
222
223        impl ops::MulAssign for $T {
224            #[inline]
225            fn mul_assign(&mut self, other: Self) {
226                *self = *self * other
227            }
228        }
229
230        impl ops::DivAssign for $T {
231            #[inline]
232            fn div_assign(&mut self, other: Self) {
233                *self = *self / other
234            }
235        }
236
237        impl ops::RemAssign for $T {
238            #[inline]
239            fn rem_assign(&mut self, other: Self) {
240                *self = *self % other
241            }
242        }
243    };
244}
245pub(crate) use impl_ops;
246
247macro_rules! impl_num_traits {
248    ($posit:ty) => {
249        impl num_traits::Zero for $posit {
250            fn zero() -> Self {
251                Self::ZERO
252            }
253            fn is_zero(&self) -> bool {
254                *self == Self::ZERO
255            }
256        }
257
258        impl num_traits::One for $posit {
259            #[inline]
260            fn one() -> Self {
261                Self::ONE
262            }
263            #[inline]
264            fn is_one(&self) -> bool {
265                *self == Self::ONE
266            }
267        }
268
269        impl num_traits::Num for $posit {
270            type FromStrRadixErr = num_traits::ParseFloatError;
271            fn from_str_radix(src: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
272                Ok(Self::from(f64::from_str_radix(src, radix)?))
273            }
274        }
275
276        impl num_traits::ToPrimitive for $posit {
277            fn to_i64(&self) -> Option<i64> {
278                Some((*self).to_i64())
279            }
280            fn to_u64(&self) -> Option<u64> {
281                Some((*self).to_u64())
282            }
283            fn to_f64(&self) -> Option<f64> {
284                Some((*self).to_f64())
285            }
286        }
287
288        impl num_traits::NumCast for $posit {
289            fn from<N: num_traits::ToPrimitive>(n: N) -> Option<Self> {
290                n.to_f64().map(|x| x.into())
291            }
292        }
293
294        impl num_traits::FromPrimitive for $posit {
295            #[inline]
296            fn from_i8(n: i8) -> Option<$posit> {
297                Some(Self::from_i8(n))
298            }
299            #[inline]
300            fn from_i16(n: i16) -> Option<$posit> {
301                Some(Self::from_i16(n))
302            }
303            #[inline]
304            fn from_i32(n: i32) -> Option<$posit> {
305                Some(Self::from_i32(n))
306            }
307            #[inline]
308            fn from_i64(n: i64) -> Option<$posit> {
309                Some(Self::from_i64(n))
310            }
311
312            #[inline]
313            fn from_u8(n: u8) -> Option<$posit> {
314                Some(Self::from_u8(n))
315            }
316            #[inline]
317            fn from_u16(n: u16) -> Option<$posit> {
318                Some(Self::from_u16(n))
319            }
320            #[inline]
321            fn from_u32(n: u32) -> Option<$posit> {
322                Some(Self::from_u32(n))
323            }
324            #[inline]
325            fn from_u64(n: u64) -> Option<$posit> {
326                Some(Self::from_u64(n))
327            }
328
329            #[inline]
330            fn from_f32(f: f32) -> Option<$posit> {
331                Some(Self::from_f32(f))
332            }
333            #[inline]
334            fn from_f64(f: f64) -> Option<$posit> {
335                Some(Self::from_f64(f))
336            }
337        }
338
339        impl num_traits::Signed for $posit {
340            fn abs(&self) -> Self {
341                Self::abs(*self)
342            }
343            fn abs_sub(&self, other: &Self) -> Self {
344                if *self <= *other {
345                    Self::ZERO
346                } else {
347                    *self - *other
348                }
349            }
350            fn signum(&self) -> Self {
351                Self::signum(*self)
352            }
353            fn is_positive(&self) -> bool {
354                !self.is_negative()
355            }
356            fn is_negative(&self) -> bool {
357                self.0 < 0
358            }
359        }
360
361        impl num_traits::Float for $posit {
362            fn nan() -> Self {
363                Self::NAR
364            }
365            fn infinity() -> Self {
366                Self::NAR
367            }
368            fn neg_infinity() -> Self {
369                Self::NAR
370            }
371            fn neg_zero() -> Self {
372                Self::ZERO
373            }
374            fn min_value() -> Self {
375                Self::MIN
376            }
377            fn min_positive_value() -> Self {
378                Self::MIN_POSITIVE
379            }
380            fn max_value() -> Self {
381                Self::MAX
382            }
383            fn is_nan(self) -> bool {
384                self == Self::NAR
385            }
386            fn is_infinite(self) -> bool {
387                self == Self::NAR
388            }
389            fn is_finite(self) -> bool {
390                !self.is_nar()
391            }
392            fn is_normal(self) -> bool {
393                !self.is_nar()
394            }
395            fn classify(self) -> core::num::FpCategory {
396                Self::classify(self)
397            }
398            fn floor(self) -> Self {
399                Self::floor(self)
400            }
401            fn ceil(self) -> Self {
402                Self::ceil(self)
403            }
404            fn round(self) -> Self {
405                Self::round(self)
406            }
407            fn trunc(self) -> Self {
408                Self::trunc(self)
409            }
410            fn fract(self) -> Self {
411                Self::fract(self)
412            }
413            fn abs(self) -> Self {
414                Self::abs(self)
415            }
416            fn signum(self) -> Self {
417                Self::signum(self)
418            }
419            fn is_sign_positive(self) -> bool {
420                Self::is_sign_positive(self)
421            }
422            fn is_sign_negative(self) -> bool {
423                Self::is_sign_negative(self)
424            }
425            fn mul_add(self, a: Self, b: Self) -> Self {
426                Self::mul_add(self, a, b)
427            }
428            fn recip(self) -> Self {
429                Self::recip(self)
430            }
431            fn powi(self, n: i32) -> Self {
432                Self::powi(self, n)
433            }
434            fn powf(self, n: Self) -> Self {
435                Self::powf(self, n)
436            }
437            fn sqrt(self) -> Self {
438                Self::sqrt(self)
439            }
440            fn exp(self) -> Self {
441                Self::exp(self)
442            }
443            fn exp2(self) -> Self {
444                Self::exp2(self)
445            }
446            fn ln(self) -> Self {
447                Self::ln(self)
448            }
449            fn log(self, base: Self) -> Self {
450                Self::log(self, base)
451            }
452            fn log2(self) -> Self {
453                Self::log2(self)
454            }
455            fn log10(self) -> Self {
456                Self::log10(self)
457            }
458            fn max(self, other: Self) -> Self {
459                core::cmp::Ord::max(self, other)
460            }
461            fn min(self, other: Self) -> Self {
462                core::cmp::Ord::min(self, other)
463            }
464            fn abs_sub(self, _other: Self) -> Self {
465                todo!()
466            }
467            fn cbrt(self) -> Self {
468                Self::cbrt(self)
469            }
470            fn hypot(self, other: Self) -> Self {
471                Self::hypot(self, other)
472            }
473            fn sin(self) -> Self {
474                Self::sin(self)
475            }
476            fn cos(self) -> Self {
477                Self::cos(self)
478            }
479            fn tan(self) -> Self {
480                Self::tan(self)
481            }
482            fn asin(self) -> Self {
483                Self::asin(self)
484            }
485            fn acos(self) -> Self {
486                Self::acos(self)
487            }
488            fn atan(self) -> Self {
489                Self::atan(self)
490            }
491            fn atan2(self, other: Self) -> Self {
492                Self::atan2(self, other)
493            }
494            fn sin_cos(self) -> (Self, Self) {
495                Self::sin_cos(self)
496            }
497            fn exp_m1(self) -> Self {
498                Self::exp_m1(self)
499            }
500            fn ln_1p(self) -> Self {
501                Self::ln_1p(self)
502            }
503            fn sinh(self) -> Self {
504                Self::sinh(self)
505            }
506            fn cosh(self) -> Self {
507                Self::cosh(self)
508            }
509            fn tanh(self) -> Self {
510                Self::tanh(self)
511            }
512            fn asinh(self) -> Self {
513                Self::asinh(self)
514            }
515            fn acosh(self) -> Self {
516                Self::acosh(self)
517            }
518            fn atanh(self) -> Self {
519                Self::atanh(self)
520            }
521            fn integer_decode(self) -> (u64, i16, i8) {
522                todo!()
523            }
524        }
525
526        use $crate::MathConsts;
527        impl num_traits::FloatConst for $posit {
528            fn E() -> Self {
529                MathConsts::E
530            }
531            fn FRAC_1_PI() -> Self {
532                MathConsts::FRAC_1_PI
533            }
534            fn FRAC_1_SQRT_2() -> Self {
535                MathConsts::FRAC_1_SQRT_2
536            }
537            fn FRAC_2_PI() -> Self {
538                MathConsts::FRAC_2_PI
539            }
540            fn FRAC_2_SQRT_PI() -> Self {
541                MathConsts::FRAC_2_SQRT_PI
542            }
543            fn FRAC_PI_2() -> Self {
544                MathConsts::FRAC_PI_2
545            }
546            fn FRAC_PI_3() -> Self {
547                MathConsts::FRAC_PI_3
548            }
549            fn FRAC_PI_4() -> Self {
550                MathConsts::FRAC_PI_4
551            }
552            fn FRAC_PI_6() -> Self {
553                MathConsts::FRAC_PI_6
554            }
555            fn FRAC_PI_8() -> Self {
556                MathConsts::FRAC_PI_8
557            }
558            fn LN_10() -> Self {
559                MathConsts::LN_10
560            }
561            fn LN_2() -> Self {
562                MathConsts::LN_2
563            }
564            fn LOG10_E() -> Self {
565                MathConsts::LOG10_E
566            }
567            fn LOG2_E() -> Self {
568                MathConsts::LOG2_E
569            }
570            fn PI() -> Self {
571                MathConsts::PI
572            }
573            fn SQRT_2() -> Self {
574                MathConsts::SQRT_2
575            }
576        }
577
578        impl num_traits::Bounded for $posit {
579            fn min_value() -> Self {
580                Self::MIN
581            }
582            fn max_value() -> Self {
583                Self::MAX
584            }
585        }
586    };
587}
588pub(crate) use impl_num_traits;
589
590macro_rules! impl_convert {
591    ($posit:ty) => {
592        impl From<i8> for $posit {
593            #[inline]
594            fn from(a: i8) -> Self {
595                Self::from_i8(a)
596            }
597        }
598
599        impl From<$posit> for i8 {
600            #[inline]
601            fn from(a: $posit) -> Self {
602                a.to_i8()
603            }
604        }
605
606        impl From<i16> for $posit {
607            #[inline]
608            fn from(a: i16) -> Self {
609                Self::from_i16(a)
610            }
611        }
612
613        impl From<$posit> for i16 {
614            #[inline]
615            fn from(a: $posit) -> Self {
616                a.to_i16()
617            }
618        }
619
620        impl From<isize> for $posit {
621            #[inline]
622            fn from(a: isize) -> Self {
623                Self::from_isize(a)
624            }
625        }
626
627        impl From<$posit> for isize {
628            #[inline]
629            fn from(a: $posit) -> Self {
630                a.to_isize()
631            }
632        }
633
634        impl From<u8> for $posit {
635            #[inline]
636            fn from(a: u8) -> Self {
637                Self::from_u8(a)
638            }
639        }
640
641        impl From<$posit> for u8 {
642            #[inline]
643            fn from(a: $posit) -> Self {
644                a.to_u8()
645            }
646        }
647
648        impl From<u16> for $posit {
649            #[inline]
650            fn from(a: u16) -> Self {
651                Self::from_u16(a)
652            }
653        }
654
655        impl From<$posit> for u16 {
656            #[inline]
657            fn from(a: $posit) -> Self {
658                a.to_u16()
659            }
660        }
661
662        impl From<usize> for $posit {
663            #[inline]
664            fn from(a: usize) -> Self {
665                Self::from_usize(a)
666            }
667        }
668
669        impl From<$posit> for usize {
670            #[inline]
671            fn from(a: $posit) -> Self {
672                a.to_usize()
673            }
674        }
675
676        impl $posit {
677            #[inline]
678            pub const fn from_i8(a: i8) -> Self {
679                Self::from_i32(a as i32)
680            }
681
682            #[inline]
683            pub const fn to_i8(self) -> i8 {
684                self.to_i32() as i8
685            }
686
687            #[inline]
688            pub const fn from_i16(a: i16) -> Self {
689                Self::from_i32(a as i32)
690            }
691
692            #[inline]
693            pub const fn to_i16(self) -> i16 {
694                self.to_i32() as i16
695            }
696
697            #[inline]
698            pub const fn from_isize(a: isize) -> Self {
699                Self::from_i64(a as i64)
700            }
701
702            #[inline]
703            pub const fn to_isize(self) -> isize {
704                self.to_i64() as isize
705            }
706
707            #[inline]
708            pub const fn from_u8(a: u8) -> Self {
709                Self::from_u32(a as u32)
710            }
711
712            #[inline]
713            pub const fn to_u8(self) -> u8 {
714                self.to_u32() as u8
715            }
716
717            #[inline]
718            pub const fn from_u16(a: u16) -> Self {
719                Self::from_u32(a as u32)
720            }
721
722            #[inline]
723            pub const fn to_u16(self) -> u16 {
724                self.to_u32() as u16
725            }
726
727            #[inline]
728            pub const fn from_usize(a: usize) -> Self {
729                Self::from_u64(a as u64)
730            }
731
732            #[inline]
733            pub const fn to_usize(self) -> usize {
734                self.to_u64() as usize
735            }
736        }
737
738        impl From<f32> for $posit {
739            #[inline]
740            fn from(float: f32) -> Self {
741                Self::from_f32(float)
742            }
743        }
744
745        impl From<f64> for $posit {
746            #[inline]
747            fn from(float: f64) -> Self {
748                Self::from_f64(float)
749            }
750        }
751
752        impl From<$posit> for f32 {
753            #[inline]
754            fn from(p_a: $posit) -> Self {
755                p_a.to_f32()
756            }
757        }
758
759        impl From<$posit> for f64 {
760            #[inline]
761            fn from(p_a: $posit) -> Self {
762                p_a.to_f64()
763            }
764        }
765
766        impl From<$posit> for i32 {
767            #[inline]
768            fn from(p_a: $posit) -> Self {
769                p_a.to_i32()
770            }
771        }
772
773        impl From<$posit> for i64 {
774            #[inline]
775            fn from(p_a: $posit) -> Self {
776                p_a.to_i64()
777            }
778        }
779
780        impl From<u32> for $posit {
781            #[inline]
782            fn from(a: u32) -> Self {
783                Self::from_u32(a)
784            }
785        }
786
787        impl From<i32> for $posit {
788            #[inline]
789            fn from(i_a: i32) -> Self {
790                Self::from_i32(i_a)
791            }
792        }
793
794        impl From<u64> for $posit {
795            #[inline]
796            fn from(a: u64) -> Self {
797                Self::from_u64(a)
798            }
799        }
800
801        impl From<i64> for $posit {
802            #[inline]
803            fn from(i_a: i64) -> Self {
804                Self::from_i64(i_a)
805            }
806        }
807
808        impl From<$posit> for u64 {
809            #[inline]
810            fn from(p_a: $posit) -> Self {
811                p_a.to_u64()
812            }
813        }
814
815        impl From<$posit> for u32 {
816            #[inline]
817            fn from(p_a: $posit) -> Self {
818                p_a.to_u32()
819            }
820        }
821    };
822}
823pub(crate) use impl_convert;
824
825macro_rules! quire_add_sub_array {
826    ($posit:ty, $quire:ty, $($i:literal),*) => {$(
827        impl ops::AddAssign<($posit, [$posit; $i])> for $quire {
828            #[inline]
829            fn add_assign(&mut self, rhs: ($posit, [$posit; $i])) {
830                for p in &rhs.1 {
831                    *self += (rhs.0, *p);
832                }
833            }
834        }
835
836        impl ops::SubAssign<($posit, [$posit; $i])> for $quire {
837            #[inline]
838            fn sub_assign(&mut self, rhs: ($posit, [$posit; $i])) {
839                for p in &rhs.1 {
840                    *self -= (rhs.0, *p);
841                }
842            }
843        }
844    )*}
845}
846pub(crate) use quire_add_sub_array;
847
848macro_rules! quire_add_sub {
849    ($posit:ty, $quire:ty) => {
850        impl ops::AddAssign<($posit, $posit)> for $quire {
851            #[inline]
852            fn add_assign(&mut self, rhs: ($posit, $posit)) {
853                let ui_a = (rhs.0).to_bits();
854                let ui_b = (rhs.1).to_bits();
855                fdp(self, ui_a, ui_b, true);
856            }
857        }
858
859        impl ops::AddAssign<($posit, ($posit, $posit))> for $quire {
860            #[inline]
861            fn add_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
862                *self += (rhs.0, (rhs.1).0);
863                *self += (rhs.0, (rhs.1).1);
864            }
865        }
866
867        impl ops::AddAssign<($posit, ($posit, $posit, $posit))> for $quire {
868            #[inline]
869            fn add_assign(&mut self, rhs: ($posit, ($posit, $posit, $posit))) {
870                *self += (rhs.0, (rhs.1).0);
871                *self += (rhs.0, (rhs.1).1);
872                *self += (rhs.0, (rhs.1).2);
873            }
874        }
875
876        impl ops::AddAssign<$posit> for $quire {
877            #[inline]
878            fn add_assign(&mut self, rhs: $posit) {
879                let ui = rhs.to_bits();
880                fdp_one(self, ui, true);
881            }
882        }
883
884        impl ops::AddAssign<(($posit, $posit), ($posit, $posit))> for $quire {
885            #[inline]
886            fn add_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
887                *self += ((rhs.0).0, (rhs.1).0);
888                *self += ((rhs.0).0, (rhs.1).1);
889                *self += ((rhs.0).1, (rhs.1).0);
890                *self += ((rhs.0).1, (rhs.1).1);
891            }
892        }
893
894        impl ops::SubAssign<($posit, $posit)> for $quire {
895            #[inline]
896            fn sub_assign(&mut self, rhs: ($posit, $posit)) {
897                let ui_a = (rhs.0).to_bits();
898                let ui_b = (rhs.1).to_bits();
899                fdp(self, ui_a, ui_b, false);
900            }
901        }
902
903        impl ops::SubAssign<$posit> for $quire {
904            #[inline]
905            fn sub_assign(&mut self, rhs: $posit) {
906                let ui = rhs.to_bits();
907                fdp_one(self, ui, false);
908            }
909        }
910
911        impl ops::SubAssign<($posit, ($posit, $posit))> for $quire {
912            #[inline]
913            fn sub_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
914                *self -= (rhs.0, (rhs.1).0);
915                *self -= (rhs.0, (rhs.1).1);
916            }
917        }
918
919        impl ops::SubAssign<(($posit, $posit), ($posit, $posit))> for $quire {
920            #[inline]
921            fn sub_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
922                *self -= ((rhs.0).0, (rhs.1).0);
923                *self -= ((rhs.0).0, (rhs.1).1);
924                *self -= ((rhs.0).1, (rhs.1).0);
925                *self -= ((rhs.0).1, (rhs.1).1);
926            }
927        }
928    };
929}
930pub(crate) use quire_add_sub;
931
932macro_rules! quire_add_sub_array_x {
933    ($posit:ty, $quire:ty, $($i:literal),*) => {$(
934        impl<const N: u32> ops::AddAssign<($posit, [$posit; $i])> for $quire {
935            #[inline]
936            fn add_assign(&mut self, rhs: ($posit, [$posit; $i])) {
937                for p in &rhs.1 {
938                    *self += (rhs.0, *p);
939                }
940            }
941        }
942
943        impl<const N: u32> ops::SubAssign<($posit, [$posit; $i])> for $quire {
944            #[inline]
945            fn sub_assign(&mut self, rhs: ($posit, [$posit; $i])) {
946                for p in &rhs.1 {
947                    *self -= (rhs.0, *p);
948                }
949            }
950        }
951    )*}
952}
953pub(crate) use quire_add_sub_array_x;
954
955macro_rules! quire_add_sub_x {
956    ($posit:ty, $quire:ty) => {
957        impl<const N: u32> ops::AddAssign<($posit, $posit)> for $quire {
958            #[inline]
959            fn add_assign(&mut self, rhs: ($posit, $posit)) {
960                let ui_a = (rhs.0).to_bits();
961                let ui_b = (rhs.1).to_bits();
962                fdp(self, ui_a, ui_b, true);
963            }
964        }
965
966        impl<const N: u32> ops::AddAssign<($posit, ($posit, $posit))> for $quire {
967            #[inline]
968            fn add_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
969                *self += (rhs.0, (rhs.1).0);
970                *self += (rhs.0, (rhs.1).1);
971            }
972        }
973
974        impl<const N: u32> ops::AddAssign<($posit, ($posit, $posit, $posit))> for $quire {
975            #[inline]
976            fn add_assign(&mut self, rhs: ($posit, ($posit, $posit, $posit))) {
977                *self += (rhs.0, (rhs.1).0);
978                *self += (rhs.0, (rhs.1).1);
979                *self += (rhs.0, (rhs.1).2);
980            }
981        }
982
983        impl<const N: u32> ops::AddAssign<$posit> for $quire {
984            #[inline]
985            fn add_assign(&mut self, rhs: $posit) {
986                let ui = rhs.to_bits();
987                fdp_one(self, ui, true);
988            }
989        }
990
991        impl<const N: u32> ops::AddAssign<(($posit, $posit), ($posit, $posit))> for $quire {
992            #[inline]
993            fn add_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
994                *self += ((rhs.0).0, (rhs.1).0);
995                *self += ((rhs.0).0, (rhs.1).1);
996                *self += ((rhs.0).1, (rhs.1).0);
997                *self += ((rhs.0).1, (rhs.1).1);
998            }
999        }
1000
1001        impl<const N: u32> ops::SubAssign<($posit, $posit)> for $quire {
1002            #[inline]
1003            fn sub_assign(&mut self, rhs: ($posit, $posit)) {
1004                let ui_a = (rhs.0).to_bits();
1005                let ui_b = (rhs.1).to_bits();
1006                fdp(self, ui_a, ui_b, false);
1007            }
1008        }
1009
1010        impl<const N: u32> ops::SubAssign<$posit> for $quire {
1011            #[inline]
1012            fn sub_assign(&mut self, rhs: $posit) {
1013                let ui = rhs.to_bits();
1014                fdp_one(self, ui, false);
1015            }
1016        }
1017
1018        impl<const N: u32> ops::SubAssign<($posit, ($posit, $posit))> for $quire {
1019            #[inline]
1020            fn sub_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
1021                *self -= (rhs.0, (rhs.1).0);
1022                *self -= (rhs.0, (rhs.1).1);
1023            }
1024        }
1025
1026        impl<const N: u32> ops::SubAssign<(($posit, $posit), ($posit, $posit))> for $quire {
1027            #[inline]
1028            fn sub_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
1029                *self -= ((rhs.0).0, (rhs.1).0);
1030                *self -= ((rhs.0).0, (rhs.1).1);
1031                *self -= ((rhs.0).1, (rhs.1).0);
1032                *self -= ((rhs.0).1, (rhs.1).1);
1033            }
1034        }
1035    };
1036}
1037pub(crate) use quire_add_sub_x;
1038
1039#[cfg(feature = "simba")]
1040pub mod simba {
1041    macro_rules! impl_real {
1042        ($T:ty) => {
1043            impl simba::scalar::RealField for $T {
1044                #[inline]
1045                fn is_sign_positive(&self) -> bool {
1046                    Self::is_sign_positive(*self)
1047                }
1048
1049                #[inline]
1050                fn is_sign_negative(&self) -> bool {
1051                    Self::is_sign_negative(*self)
1052                }
1053
1054                #[inline]
1055                fn copysign(self, sign: Self) -> Self {
1056                    Self::copysign(self, sign)
1057                }
1058
1059                #[inline]
1060                fn max(self, other: Self) -> Self {
1061                    core::cmp::Ord::max(self, other)
1062                }
1063
1064                #[inline]
1065                fn min(self, other: Self) -> Self {
1066                    core::cmp::Ord::min(self, other)
1067                }
1068
1069                #[inline]
1070                fn clamp(self, min: Self, max: Self) -> Self {
1071                    Self::clamp(self, min, max)
1072                }
1073
1074                #[inline]
1075                fn atan2(self, other: Self) -> Self {
1076                    Self::atan2(self, other)
1077                }
1078
1079                #[inline]
1080                fn min_value() -> Option<Self> {
1081                    Some(Self::MIN)
1082                }
1083
1084                #[inline]
1085                fn max_value() -> Option<Self> {
1086                    Some(Self::MAX)
1087                }
1088
1089                /// Archimedes' constant.
1090                #[inline]
1091                fn pi() -> Self {
1092                    MathConsts::PI
1093                }
1094
1095                /// 2.0 * pi.
1096                #[inline]
1097                fn two_pi() -> Self {
1098                    <Self as MathConsts>::PI + <Self as MathConsts>::PI
1099                }
1100
1101                /// pi / 2.0.
1102                #[inline]
1103                fn frac_pi_2() -> Self {
1104                    MathConsts::FRAC_PI_2
1105                }
1106
1107                /// pi / 3.0.
1108                #[inline]
1109                fn frac_pi_3() -> Self {
1110                    MathConsts::FRAC_PI_3
1111                }
1112
1113                /// pi / 4.0.
1114                #[inline]
1115                fn frac_pi_4() -> Self {
1116                    MathConsts::FRAC_PI_4
1117                }
1118
1119                /// pi / 6.0.
1120                #[inline]
1121                fn frac_pi_6() -> Self {
1122                    MathConsts::FRAC_PI_6
1123                }
1124
1125                /// pi / 8.0.
1126                #[inline]
1127                fn frac_pi_8() -> Self {
1128                    MathConsts::FRAC_PI_8
1129                }
1130
1131                /// 1.0 / pi.
1132                #[inline]
1133                fn frac_1_pi() -> Self {
1134                    MathConsts::FRAC_1_PI
1135                }
1136
1137                /// 2.0 / pi.
1138                #[inline]
1139                fn frac_2_pi() -> Self {
1140                    MathConsts::FRAC_2_PI
1141                }
1142
1143                /// 2.0 / sqrt(pi).
1144                #[inline]
1145                fn frac_2_sqrt_pi() -> Self {
1146                    MathConsts::FRAC_2_SQRT_PI
1147                }
1148
1149                /// Euler's number.
1150                #[inline]
1151                fn e() -> Self {
1152                    MathConsts::E
1153                }
1154
1155                /// log2(e).
1156                #[inline]
1157                fn log2_e() -> Self {
1158                    MathConsts::LOG2_E
1159                }
1160
1161                /// log10(e).
1162                #[inline]
1163                fn log10_e() -> Self {
1164                    MathConsts::LOG10_E
1165                }
1166
1167                /// ln(2.0).
1168                #[inline]
1169                fn ln_2() -> Self {
1170                    MathConsts::LN_2
1171                }
1172
1173                /// ln(10.0).
1174                #[inline]
1175                fn ln_10() -> Self {
1176                    MathConsts::LN_10
1177                }
1178            }
1179        };
1180    }
1181    pub(crate) use impl_real;
1182
1183    macro_rules! impl_complex {
1184        ($T:ty) => {
1185            impl simba::scalar::ComplexField for $T {
1186                type RealField = $T;
1187
1188                #[inline]
1189                fn from_real(re: Self::RealField) -> Self {
1190                    re
1191                }
1192
1193                #[inline]
1194                fn real(self) -> Self::RealField {
1195                    self
1196                }
1197
1198                #[inline]
1199                fn imaginary(self) -> Self::RealField {
1200                    Self::ZERO
1201                }
1202
1203                #[inline]
1204                fn norm1(self) -> Self::RealField {
1205                    Self::abs(self)
1206                }
1207
1208                #[inline]
1209                fn modulus(self) -> Self::RealField {
1210                    Self::abs(self)
1211                }
1212
1213                #[inline]
1214                fn modulus_squared(self) -> Self::RealField {
1215                    self * self
1216                }
1217
1218                #[inline]
1219                fn argument(self) -> Self::RealField {
1220                    if self >= Self::ZERO {
1221                        Self::ZERO
1222                    } else {
1223                        MathConsts::PI
1224                    }
1225                }
1226
1227                #[inline]
1228                fn to_exp(self) -> (Self, Self) {
1229                    if self >= Self::ZERO {
1230                        (self, Self::ONE)
1231                    } else {
1232                        (-self, -Self::ONE)
1233                    }
1234                }
1235
1236                #[inline]
1237                fn recip(self) -> Self {
1238                    Self::recip(self)
1239                }
1240
1241                #[inline]
1242                fn conjugate(self) -> Self {
1243                    self
1244                }
1245
1246                #[inline]
1247                fn scale(self, factor: Self::RealField) -> Self {
1248                    self * factor
1249                }
1250
1251                #[inline]
1252                fn unscale(self, factor: Self::RealField) -> Self {
1253                    self / factor
1254                }
1255
1256                #[inline]
1257                fn floor(self) -> Self {
1258                    Self::floor(self)
1259                }
1260
1261                #[inline]
1262                fn ceil(self) -> Self {
1263                    Self::ceil(self)
1264                }
1265
1266                #[inline]
1267                fn round(self) -> Self {
1268                    Self::round(self)
1269                }
1270
1271                #[inline]
1272                fn trunc(self) -> Self {
1273                    Self::trunc(self)
1274                }
1275
1276                #[inline]
1277                fn fract(self) -> Self {
1278                    Self::fract(self)
1279                }
1280
1281                #[inline]
1282                fn abs(self) -> Self {
1283                    Self::abs(self)
1284                }
1285
1286                #[inline]
1287                fn signum(self) -> Self {
1288                    Self::signum(self)
1289                }
1290
1291                #[inline]
1292                fn mul_add(self, a: Self, b: Self) -> Self {
1293                    Self::mul_add(self, a, b)
1294                }
1295
1296                #[inline]
1297                fn powi(self, n: i32) -> Self {
1298                    Self::powi(self, n)
1299                }
1300
1301                #[inline]
1302                fn powf(self, n: Self) -> Self {
1303                    Self::powf(self, n)
1304                }
1305
1306                #[inline]
1307                fn powc(self, n: Self) -> Self {
1308                    // Same as powf.
1309                    Self::powf(self, n)
1310                }
1311
1312                #[inline]
1313                fn sqrt(self) -> Self {
1314                    Self::sqrt(self)
1315                }
1316
1317                #[inline]
1318                fn try_sqrt(self) -> Option<Self> {
1319                    if self >= Self::ZERO {
1320                        Some(Self::sqrt(self))
1321                    } else {
1322                        None
1323                    }
1324                }
1325
1326                #[inline]
1327                fn exp(self) -> Self {
1328                    Self::exp(self)
1329                }
1330
1331                #[inline]
1332                fn exp2(self) -> Self {
1333                    Self::exp2(self)
1334                }
1335
1336                #[inline]
1337                fn exp_m1(self) -> Self {
1338                    Self::exp_m1(self)
1339                }
1340
1341                #[inline]
1342                fn ln_1p(self) -> Self {
1343                    Self::ln_1p(self)
1344                }
1345
1346                #[inline]
1347                fn ln(self) -> Self {
1348                    Self::ln(self)
1349                }
1350
1351                #[inline]
1352                fn log(self, base: Self) -> Self {
1353                    Self::log(self, base)
1354                }
1355
1356                #[inline]
1357                fn log2(self) -> Self {
1358                    Self::log2(self)
1359                }
1360
1361                #[inline]
1362                fn log10(self) -> Self {
1363                    Self::log10(self)
1364                }
1365
1366                #[inline]
1367                fn cbrt(self) -> Self {
1368                    Self::cbrt(self)
1369                }
1370
1371                #[inline]
1372                fn hypot(self, other: Self) -> Self::RealField {
1373                    Self::hypot(self, other)
1374                }
1375
1376                #[inline]
1377                fn sin(self) -> Self {
1378                    Self::sin(self)
1379                }
1380
1381                #[inline]
1382                fn cos(self) -> Self {
1383                    Self::cos(self)
1384                }
1385
1386                #[inline]
1387                fn tan(self) -> Self {
1388                    Self::tan(self)
1389                }
1390
1391                #[inline]
1392                fn asin(self) -> Self {
1393                    Self::asin(self)
1394                }
1395
1396                #[inline]
1397                fn acos(self) -> Self {
1398                    Self::acos(self)
1399                }
1400
1401                #[inline]
1402                fn atan(self) -> Self {
1403                    Self::atan(self)
1404                }
1405
1406                #[inline]
1407                fn sin_cos(self) -> (Self, Self) {
1408                    Self::sin_cos(self)
1409                }
1410
1411                #[inline]
1412                fn sinh(self) -> Self {
1413                    Self::sinh(self)
1414                }
1415
1416                #[inline]
1417                fn cosh(self) -> Self {
1418                    Self::cosh(self)
1419                }
1420
1421                #[inline]
1422                fn tanh(self) -> Self {
1423                    Self::tanh(self)
1424                }
1425
1426                #[inline]
1427                fn asinh(self) -> Self {
1428                    Self::asinh(self)
1429                }
1430
1431                #[inline]
1432                fn acosh(self) -> Self {
1433                    Self::acosh(self)
1434                }
1435
1436                #[inline]
1437                fn atanh(self) -> Self {
1438                    Self::atanh(self)
1439                }
1440
1441                #[inline]
1442                fn is_finite(&self) -> bool {
1443                    Self::is_finite(*self)
1444                }
1445            }
1446        };
1447    }
1448    pub(crate) use impl_complex;
1449
1450    macro_rules! impl_primitive_simd_value_for_scalar(
1451        ($($t: ty),*) => {$(
1452            impl simba::simd::PrimitiveSimdValue for $t {}
1453            impl simba::simd::SimdValue for $t {
1454                type Element = $t;
1455                type SimdBool = bool;
1456
1457                #[inline(always)]
1458                fn lanes() -> usize {
1459                    1
1460                }
1461
1462                #[inline(always)]
1463                fn splat(val: Self::Element) -> Self {
1464                    val
1465                }
1466
1467                #[inline(always)]
1468                fn extract(&self, _: usize) -> Self::Element {
1469                    *self
1470                }
1471
1472                #[inline(always)]
1473                unsafe fn extract_unchecked(&self, _: usize) -> Self::Element {
1474                    *self
1475                }
1476
1477                #[inline(always)]
1478                fn replace(&mut self, _: usize, val: Self::Element) {
1479                    *self = val
1480                }
1481
1482                #[inline(always)]
1483                unsafe fn replace_unchecked(&mut self, _: usize, val: Self::Element) {
1484                    *self = val
1485                }
1486
1487                #[inline(always)]
1488                fn select(self, cond: Self::SimdBool, other: Self) -> Self {
1489                    if cond {
1490                        self
1491                    } else {
1492                        other
1493                    }
1494                }
1495            }
1496        )*}
1497    );
1498    pub(crate) use impl_primitive_simd_value_for_scalar;
1499
1500    macro_rules! impl_subset_into(
1501    ($($subset: ty as $( $superset: ty),+ );* $(;)*) => {
1502        $($(
1503            impl simba::scalar::SubsetOf<$superset> for $subset {
1504                #[inline]
1505                fn to_superset(&self) -> $superset {
1506                    (*self).into()
1507                }
1508
1509                #[inline]
1510                fn from_superset_unchecked(element: &$superset) -> $subset {
1511                    (*element).into()
1512                }
1513
1514                #[inline]
1515                fn is_in_subset(_: &$superset) -> bool {
1516                    true
1517                }
1518            }
1519        )+)*
1520    });
1521    pub(crate) use impl_subset_into;
1522}
1523
1524#[cfg(feature = "approx")]
1525pub mod approx {
1526    macro_rules! impl_ulps_eq {
1527        ($T:ident, $U:ident) => {
1528            impl approx::UlpsEq for $T {
1529                #[inline]
1530                fn default_max_ulps() -> u32 {
1531                    4
1532                }
1533
1534                #[inline]
1535                fn ulps_eq(&self, other: &$T, epsilon: $T, max_ulps: u32) -> bool {
1536                    // For when the numbers are really close together
1537                    if $T::abs_diff_eq(self, other, epsilon) {
1538                        return true;
1539                    }
1540
1541                    // Trivial negative sign check
1542                    if self.signum() != other.signum() {
1543                        return false;
1544                    }
1545
1546                    // ULPS difference comparison
1547                    let int_self: $U = unsafe { core::mem::transmute(*self) };
1548                    let int_other: $U = unsafe { core::mem::transmute(*other) };
1549
1550                    $U::abs(int_self - int_other) <= max_ulps as $U
1551                }
1552            }
1553        };
1554    }
1555    pub(crate) use impl_ulps_eq;
1556
1557    macro_rules! impl_signed_abs_diff_eq {
1558        ($T:ident, $default_epsilon:expr) => {
1559            impl approx::AbsDiffEq for $T {
1560                type Epsilon = $T;
1561
1562                #[inline]
1563                fn default_epsilon() -> $T {
1564                    $default_epsilon
1565                }
1566
1567                #[inline]
1568                fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
1569                    $T::abs(*self - *other) <= epsilon
1570                }
1571            }
1572        };
1573    }
1574    pub(crate) use impl_signed_abs_diff_eq;
1575
1576    macro_rules! impl_relative_eq {
1577        ($T:ident, $U:ident) => {
1578            impl approx::RelativeEq for $T {
1579                #[inline]
1580                fn default_max_relative() -> $T {
1581                    $T::EPSILON
1582                }
1583
1584                #[inline]
1585                fn relative_eq(&self, other: &$T, epsilon: $T, max_relative: $T) -> bool {
1586                    // Handle same infinities
1587                    if self == other {
1588                        return true;
1589                    }
1590
1591                    // Handle remaining infinities
1592                    if $T::is_infinite(*self) || $T::is_infinite(*other) {
1593                        return false;
1594                    }
1595
1596                    let abs_diff = $T::abs(*self - *other);
1597
1598                    // For when the numbers are really close together
1599                    if abs_diff <= epsilon {
1600                        return true;
1601                    }
1602
1603                    let abs_self = $T::abs(*self);
1604                    let abs_other = $T::abs(*other);
1605
1606                    let largest = if abs_other > abs_self {
1607                        abs_other
1608                    } else {
1609                        abs_self
1610                    };
1611
1612                    // Use a relative difference comparison
1613                    abs_diff <= largest * max_relative
1614                }
1615            }
1616        };
1617    }
1618    pub(crate) use impl_relative_eq;
1619}