Skip to main content

number_general/
instance.rs

1use std::cmp::Ordering;
2use std::fmt;
3use std::hash::{Hash, Hasher};
4use std::iter::{Product, Sum};
5use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
6use std::str::FromStr;
7
8use collate::Collate;
9use get_size::GetSize;
10use num::traits::Pow;
11use safecast::{CastFrom, CastInto};
12
13use super::class::{
14    BooleanType, ComplexType, FloatInstance, FloatType, IntType, NumberClass, NumberInstance,
15    RealInstance, Trigonometry, UIntType,
16};
17use super::{Error, Number, _Complex};
18
19const ERR_COMPLEX_POWER: &str = "complex exponent is not yet supported";
20
21macro_rules! fmt_debug {
22    ($t:ty) => {
23        impl fmt::Debug for $t {
24            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25                write!(f, "{} ({})", self, self.class())
26            }
27        }
28    };
29}
30
31/// A boolean value.
32#[derive(Clone, Copy, Default, Hash, Ord, PartialEq, PartialOrd)]
33pub struct Boolean(bool);
34
35impl GetSize for Boolean {
36    fn get_size(&self) -> usize {
37        1
38    }
39}
40
41impl Boolean {
42    fn as_radians(self) -> f32 {
43        if self.0 {
44            2. * std::f32::consts::PI
45        } else {
46            0.
47        }
48    }
49}
50
51impl NumberInstance for Boolean {
52    type Abs = Self;
53    type Exp = Float;
54    type Log = Float;
55    type Round = Self;
56    type Class = BooleanType;
57
58    fn class(&self) -> BooleanType {
59        BooleanType
60    }
61
62    fn into_type(self, _dtype: BooleanType) -> Boolean {
63        self
64    }
65
66    fn abs(self) -> Self {
67        self
68    }
69
70    fn exp(self) -> Self::Exp {
71        Float::cast_from(self).exp()
72    }
73
74    fn ln(self) -> Self::Log {
75        Float::cast_from(self).ln()
76    }
77
78    fn log<N: NumberInstance>(self, base: N) -> Self::Log
79    where
80        Float: From<N>,
81    {
82        Float::cast_from(self).log(base)
83    }
84
85    fn pow(self, exp: Number) -> Self {
86        if exp.cast_into() {
87            self
88        } else {
89            self.class().one()
90        }
91    }
92
93    fn and(self, other: Self) -> Self {
94        Self(self.0 && other.0)
95    }
96
97    fn not(self) -> Self {
98        Self(!self.0)
99    }
100
101    fn or(self, other: Self) -> Self {
102        Self(self.0 || other.0)
103    }
104
105    fn round(self) -> Self::Round {
106        self
107    }
108
109    fn xor(self, other: Self) -> Self {
110        Self(self.0 ^ other.0)
111    }
112}
113
114impl RealInstance for Boolean {
115    const ONE: Self = Boolean(true);
116    const ZERO: Self = Boolean(false);
117}
118
119impl From<bool> for Boolean {
120    fn from(b: bool) -> Boolean {
121        Self(b)
122    }
123}
124
125impl FromStr for Boolean {
126    type Err = Error;
127
128    fn from_str(s: &str) -> Result<Self, Self::Err> {
129        bool::from_str(s).map(Self::from).map_err(Error::new)
130    }
131}
132
133impl From<Boolean> for bool {
134    fn from(b: Boolean) -> bool {
135        b.0
136    }
137}
138
139impl From<&Boolean> for bool {
140    fn from(b: &Boolean) -> bool {
141        b.0
142    }
143}
144
145impl Eq for Boolean {}
146
147impl Add for Boolean {
148    type Output = Self;
149
150    fn add(self, other: Self) -> Self::Output {
151        self.or(other)
152    }
153}
154
155impl AddAssign for Boolean {
156    fn add_assign(&mut self, other: Self) {
157        self.0 = self.0 || other.0;
158    }
159}
160
161impl Rem for Boolean {
162    type Output = Self;
163
164    fn rem(self, other: Self) -> Self::Output {
165        self.xor(other)
166    }
167}
168
169impl RemAssign for Boolean {
170    fn rem_assign(&mut self, other: Self) {
171        *self = *self % other;
172    }
173}
174
175impl Sub for Boolean {
176    type Output = Self;
177
178    fn sub(self, other: Self) -> Self::Output {
179        self.xor(other)
180    }
181}
182
183impl SubAssign for Boolean {
184    fn sub_assign(&mut self, other: Self) {
185        self.0 = self.0 != other.0;
186    }
187}
188
189impl Sum for Boolean {
190    fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self {
191        Self(iter.any(|b| b.0))
192    }
193}
194
195impl Mul for Boolean {
196    type Output = Self;
197
198    fn mul(self, other: Self) -> Self {
199        self.and(other)
200    }
201}
202
203impl MulAssign for Boolean {
204    fn mul_assign(&mut self, other: Self) {
205        self.0 = self.0 && other.0;
206    }
207}
208
209impl Div for Boolean {
210    type Output = Self;
211
212    fn div(self, other: Self) -> Self::Output {
213        if let Self(false) = other {
214            panic!("divide by zero!")
215        } else {
216            self
217        }
218    }
219}
220
221impl DivAssign for Boolean {
222    fn div_assign(&mut self, other: Self) {
223        let div = *self / other;
224        *self = div;
225    }
226}
227
228impl Product for Boolean {
229    fn product<I: Iterator<Item = Self>>(mut iter: I) -> Self {
230        Self(iter.all(|b| b.0))
231    }
232}
233
234macro_rules! trig_bool {
235    ($fun:ident) => {
236        fn $fun(self) -> Self::Out {
237            self.as_radians().$fun().into()
238        }
239    };
240}
241
242impl Trigonometry for Boolean {
243    type Out = Float;
244
245    trig_bool! {asin}
246    trig_bool! {sin}
247    trig_bool! {sinh}
248    trig_bool! {asinh}
249
250    trig_bool! {acos}
251    trig_bool! {cos}
252    trig_bool! {cosh}
253    trig_bool! {acosh}
254
255    trig_bool! {atan}
256    trig_bool! {tan}
257    trig_bool! {tanh}
258    trig_bool! {atanh}
259}
260
261impl CastFrom<Boolean> for u64 {
262    fn cast_from(b: Boolean) -> u64 {
263        UInt::from(b).into()
264    }
265}
266
267fmt_debug!(Boolean);
268
269impl fmt::Display for Boolean {
270    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271        fmt::Display::fmt(&self.0, f)
272    }
273}
274
275/// A complex number.
276#[derive(Clone, Copy)]
277pub enum Complex {
278    C32(_Complex<f32>),
279    C64(_Complex<f64>),
280}
281
282impl GetSize for Complex {
283    fn get_size(&self) -> usize {
284        match self {
285            Self::C32(c) => c.re.get_size() + c.im.get_size(),
286            Self::C64(c) => c.re.get_size() + c.im.get_size(),
287        }
288    }
289}
290
291impl Complex {
292    /// Borrow the imaginary part of this [`Complex`] number
293    pub fn im(&self) -> Float {
294        match self {
295            Self::C32(c) => Float::F32(c.im),
296            Self::C64(c) => Float::F64(c.im),
297        }
298    }
299
300    /// Borrow the real part of this [`Complex`] number
301    pub fn re(&self) -> Float {
302        match self {
303            Self::C32(c) => Float::F32(c.re),
304            Self::C64(c) => Float::F64(c.re),
305        }
306    }
307}
308
309impl NumberInstance for Complex {
310    type Abs = Float;
311    type Exp = Self;
312    type Log = Self;
313    type Round = Self;
314    type Class = ComplexType;
315
316    fn class(&self) -> ComplexType {
317        match self {
318            Self::C32(_) => ComplexType::C32,
319            Self::C64(_) => ComplexType::C64,
320        }
321    }
322
323    fn into_type(self, dtype: ComplexType) -> Complex {
324        use ComplexType::*;
325        match dtype {
326            C32 => match self {
327                Self::C64(c) => Self::C32(_Complex::new(c.re as f32, c.im as f32)),
328                this => this,
329            },
330            C64 => match self {
331                Self::C32(c) => Self::C64(_Complex::new(c.re as f64, c.im as f64)),
332                this => this,
333            },
334            Complex => self,
335        }
336    }
337
338    fn abs(self) -> Float {
339        match self {
340            Self::C32(c) => Float::F32(c.norm_sqr().sqrt()),
341            Self::C64(c) => Float::F64(c.norm_sqr().sqrt()),
342        }
343    }
344
345    fn exp(self) -> Self::Exp {
346        match self {
347            Self::C32(c) => Self::C32(c.exp()),
348            Self::C64(c) => Self::C64(c.exp()),
349        }
350    }
351
352    fn ln(self) -> Self::Log {
353        match self {
354            Self::C32(c) => c.ln().into(),
355            Self::C64(c) => c.ln().into(),
356        }
357    }
358
359    fn log<N: NumberInstance>(self, base: N) -> Self::Log
360    where
361        Float: From<N>,
362    {
363        match self {
364            Self::C32(c) => c.log(Float::from(base).cast_into()).into(),
365            Self::C64(c) => c.log(Float::from(base).cast_into()).into(),
366        }
367    }
368
369    fn pow(self, exp: Number) -> Self {
370        match self {
371            Self::C64(this) => match exp {
372                Number::Complex(exp) => unimplemented!("{}: {}", ERR_COMPLEX_POWER, exp),
373                Number::Float(Float::F64(exp)) => Self::C64(this.pow(exp)),
374                Number::Float(Float::F32(exp)) => Self::C64(this.pow(exp)),
375                exp => Self::C64(this.pow(f64::cast_from(exp))),
376            },
377            Self::C32(this) => match exp {
378                Number::Complex(exp) => unimplemented!("{}: {}", ERR_COMPLEX_POWER, exp),
379                Number::Float(Float::F64(exp)) => {
380                    let this = _Complex::<f64>::new(this.re.into(), this.im.into());
381                    Self::C64(this.pow(exp))
382                }
383                Number::Float(Float::F32(exp)) => Self::C32(this.pow(exp)),
384                exp => Self::C32(this.pow(f32::cast_from(exp))),
385            },
386        }
387    }
388
389    fn round(self) -> Self::Round {
390        match self {
391            Self::C32(c) => Self::C32(_Complex::new(c.re.round(), c.im.round())),
392            Self::C64(c) => Self::C64(_Complex::new(c.re.round(), c.im.round())),
393        }
394    }
395}
396
397impl FloatInstance for Complex {
398    fn is_infinite(&self) -> bool {
399        match self {
400            Self::C32(c) => c.im.is_infinite() || c.re.is_infinite(),
401            Self::C64(c) => c.im.is_infinite() || c.re.is_infinite(),
402        }
403    }
404
405    fn is_nan(&self) -> bool {
406        match self {
407            Self::C32(c) => c.im.is_nan() || c.re.is_nan(),
408            Self::C64(c) => c.im.is_nan() || c.re.is_nan(),
409        }
410    }
411}
412
413impl From<[f32; 2]> for Complex {
414    fn from(arr: [f32; 2]) -> Self {
415        Self::C32(num::Complex::new(arr[0], arr[1]))
416    }
417}
418
419impl From<[f64; 2]> for Complex {
420    fn from(arr: [f64; 2]) -> Self {
421        Self::C64(num::Complex::new(arr[0], arr[1]))
422    }
423}
424
425impl<R, I> From<(R, I)> for Complex
426where
427    R: Into<f64>,
428    I: Into<f64>,
429{
430    fn from(value: (R, I)) -> Self {
431        let re = value.0.into();
432        let im = value.1.into();
433        Self::C64(num::Complex::new(re, im))
434    }
435}
436
437impl CastFrom<Number> for Complex {
438    fn cast_from(number: Number) -> Complex {
439        use Number::*;
440        match number {
441            Number::Bool(b) => Self::from(b),
442            Complex(c) => c,
443            Float(f) => Self::from(f),
444            Int(i) => Self::from(i),
445            UInt(u) => Self::from(u),
446        }
447    }
448}
449
450impl CastFrom<Complex> for Boolean {
451    fn cast_from(c: Complex) -> Self {
452        match c {
453            Complex::C32(c) if c.norm_sqr() == 0f32 => Self(false),
454            Complex::C64(c) if c.norm_sqr() == 0f64 => Self(false),
455            _ => Self(true),
456        }
457    }
458}
459
460impl CastFrom<Complex> for _Complex<f32> {
461    fn cast_from(c: Complex) -> Self {
462        match c {
463            Complex::C32(c) => c,
464            Complex::C64(_Complex { re, im }) => Self::new(re as f32, im as f32),
465        }
466    }
467}
468
469impl Add for Complex {
470    type Output = Self;
471
472    fn add(self, other: Complex) -> Self {
473        match (self, other) {
474            (Self::C32(l), Self::C32(r)) => Self::C32(l + r),
475            (Self::C64(l), Self::C64(r)) => Self::C64(l + r),
476            (Self::C64(l), r) => {
477                let r: _Complex<f64> = r.into();
478                Self::C64(l + r)
479            }
480            (l, r) => r + l,
481        }
482    }
483}
484
485impl AddAssign for Complex {
486    fn add_assign(&mut self, other: Self) {
487        let sum = *self + other;
488        *self = sum;
489    }
490}
491
492impl Rem for Complex {
493    type Output = Self;
494
495    fn rem(self, other: Self) -> Self::Output {
496        match (self, other) {
497            (Self::C32(l), Self::C32(r)) => Self::C32(l - r),
498            (l, r) => {
499                let l: _Complex<f64> = l.into();
500                let r: _Complex<f64> = r.into();
501                Self::C64(l % r)
502            }
503        }
504    }
505}
506
507impl Sub for Complex {
508    type Output = Self;
509
510    fn sub(self, other: Complex) -> Self {
511        match (self, other) {
512            (Self::C32(l), Self::C32(r)) => Self::C32(l - r),
513            (l, r) => {
514                let l: _Complex<f64> = l.into();
515                let r: _Complex<f64> = r.into();
516                Self::C64(l - r)
517            }
518        }
519    }
520}
521
522impl SubAssign for Complex {
523    fn sub_assign(&mut self, other: Self) {
524        let diff = *self - other;
525        *self = diff;
526    }
527}
528
529impl Sum for Complex {
530    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
531        let mut sum = ComplexType::Complex.zero();
532        for i in iter {
533            sum += i;
534        }
535        sum
536    }
537}
538
539impl Mul for Complex {
540    type Output = Self;
541
542    fn mul(self, other: Complex) -> Self {
543        match (self, other) {
544            (Self::C32(l), Self::C32(r)) => Self::C32(l * r),
545            (Self::C64(l), Self::C64(r)) => Self::C64(l * r),
546            (Self::C64(l), r) => {
547                let r: _Complex<f64> = r.into();
548                Self::C64(l * r)
549            }
550            (l, r) => r * l,
551        }
552    }
553}
554
555impl MulAssign for Complex {
556    fn mul_assign(&mut self, other: Self) {
557        let product = *self * other;
558        *self = product;
559    }
560}
561
562impl Div for Complex {
563    type Output = Self;
564
565    fn div(self, other: Complex) -> Self {
566        match (self, other) {
567            (Self::C32(l), Self::C32(r)) => Self::C32(l / r),
568            (Self::C64(l), Self::C64(r)) => Self::C64(l / r),
569            (Self::C64(l), r) => {
570                let r: _Complex<f64> = r.into();
571                Self::C64(l / r)
572            }
573            (Self::C32(l), Self::C64(r)) => {
574                let l = _Complex::<f64>::new(l.re as f64, l.im as f64);
575                Self::C64(l / r)
576            }
577        }
578    }
579}
580
581impl DivAssign for Complex {
582    fn div_assign(&mut self, other: Self) {
583        let div = *self / other;
584        *self = div;
585    }
586}
587
588impl Product for Complex {
589    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
590        let zero = ComplexType::Complex.zero();
591        let mut product = ComplexType::Complex.one();
592
593        for i in iter {
594            if i == zero {
595                return zero;
596            }
597
598            product *= i;
599        }
600        product
601    }
602}
603
604macro_rules! trig_complex {
605    ($fun:ident) => {
606        fn $fun(self) -> Self {
607            match self {
608                Complex::C32(c) => c.$fun().into(),
609                Complex::C64(c) => c.$fun().into(),
610            }
611        }
612    };
613}
614
615impl Trigonometry for Complex {
616    type Out = Self;
617
618    trig_complex! {asin}
619    trig_complex! {sin}
620    trig_complex! {sinh}
621    trig_complex! {asinh}
622
623    trig_complex! {acos}
624    trig_complex! {cos}
625    trig_complex! {cosh}
626    trig_complex! {acosh}
627
628    trig_complex! {atan}
629    trig_complex! {tan}
630    trig_complex! {tanh}
631    trig_complex! {atanh}
632}
633
634impl PartialEq for Complex {
635    fn eq(&self, other: &Self) -> bool {
636        let l: _Complex<f32> = (*self).cast_into();
637        let r: _Complex<f32> = (*other).cast_into();
638
639        super::normalized_f32_bits(l.re) == super::normalized_f32_bits(r.re)
640            && super::normalized_f32_bits(l.im) == super::normalized_f32_bits(r.im)
641    }
642}
643
644impl Eq for Complex {}
645
646impl Hash for Complex {
647    fn hash<H: Hasher>(&self, state: &mut H) {
648        let c: _Complex<f32> = (*self).cast_into();
649        super::normalized_f32_bits(c.re).hash(state);
650        super::normalized_f32_bits(c.im).hash(state);
651    }
652}
653
654impl Default for Complex {
655    fn default() -> Complex {
656        Complex::C32(_Complex::<f32>::default())
657    }
658}
659
660impl From<Complex> for _Complex<f64> {
661    fn from(c: Complex) -> Self {
662        match c {
663            Complex::C32(c) => Self::new(c.re as f64, c.im as f64),
664            Complex::C64(c64) => c64,
665        }
666    }
667}
668
669impl From<Float> for Complex {
670    fn from(f: Float) -> Self {
671        match f {
672            Float::F64(f) => Self::C64(_Complex::new(f, 0.0f64)),
673            Float::F32(f) => Self::C32(_Complex::new(f, 0.0f32)),
674        }
675    }
676}
677
678impl From<Int> for Complex {
679    fn from(i: Int) -> Self {
680        match i {
681            Int::I8(i) => Self::C32(_Complex::new(i as f32, 0.0f32)),
682            Int::I64(i) => Self::C64(_Complex::new(i as f64, 0.0f64)),
683            Int::I32(i) => Self::C32(_Complex::new(i as f32, 0.0f32)),
684            Int::I16(i) => Self::C32(_Complex::new(i as f32, 0.0f32)),
685        }
686    }
687}
688
689impl From<UInt> for Complex {
690    fn from(u: UInt) -> Self {
691        match u {
692            UInt::U64(u) => Self::C64(_Complex::new(u as f64, 0.0f64)),
693            UInt::U32(u) => Self::C32(_Complex::new(u as f32, 0.0f32)),
694            UInt::U16(u) => Self::C32(_Complex::new(u as f32, 0.0f32)),
695            UInt::U8(u) => Self::C32(_Complex::new(u as f32, 0.0f32)),
696        }
697    }
698}
699
700impl From<Boolean> for Complex {
701    fn from(b: Boolean) -> Self {
702        match b {
703            Boolean(true) => Self::C32(_Complex::new(1.0f32, 0.0f32)),
704            Boolean(false) => Self::C32(_Complex::new(0.0f32, 0.0f32)),
705        }
706    }
707}
708
709impl From<_Complex<f32>> for Complex {
710    fn from(c: _Complex<f32>) -> Self {
711        Self::C32(c)
712    }
713}
714
715impl From<_Complex<f64>> for Complex {
716    fn from(c: _Complex<f64>) -> Self {
717        Self::C64(c)
718    }
719}
720
721impl FromStr for Complex {
722    type Err = Error;
723
724    fn from_str(s: &str) -> Result<Self, Self::Err> {
725        num::Complex::<f64>::from_str(s)
726            .map(Self::from)
727            .map_err(Error::new)
728    }
729}
730
731impl From<Complex> for (Float, Float) {
732    fn from(n: Complex) -> Self {
733        match n {
734            Complex::C32(n) => (Float::F32(n.re), Float::F32(n.im)),
735            Complex::C64(n) => (Float::F64(n.re), Float::F64(n.im)),
736        }
737    }
738}
739
740impl From<Complex> for [Float; 2] {
741    fn from(n: Complex) -> Self {
742        match n {
743            Complex::C32(n) => [Float::F32(n.re), Float::F32(n.im)],
744            Complex::C64(n) => [Float::F64(n.re), Float::F64(n.im)],
745        }
746    }
747}
748
749fmt_debug!(Complex);
750
751impl fmt::Display for Complex {
752    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
753        match self {
754            Complex::C32(c) => fmt::Display::fmt(c, f),
755            Complex::C64(c) => fmt::Display::fmt(c, f),
756        }
757    }
758}
759
760/// Defines a collation order for [`Complex`].
761#[derive(Copy, Clone, Default, Eq, PartialEq)]
762pub struct ComplexCollator {
763    float: FloatCollator,
764}
765
766impl Collate for ComplexCollator {
767    type Value = Complex;
768
769    fn cmp(&self, left: &Self::Value, right: &Self::Value) -> Ordering {
770        self.float.cmp(&left.abs(), &right.abs())
771    }
772}
773
774/// A floating-point number.
775#[derive(Clone, Copy, get_size_derive::GetSize)]
776pub enum Float {
777    F32(f32),
778    F64(f64),
779}
780
781impl NumberInstance for Float {
782    type Abs = Float;
783    type Exp = Self;
784    type Log = Self;
785    type Round = Int;
786    type Class = FloatType;
787
788    fn class(&self) -> FloatType {
789        match self {
790            Self::F32(_) => FloatType::F32,
791            Self::F64(_) => FloatType::F64,
792        }
793    }
794
795    fn into_type(self, dtype: FloatType) -> Float {
796        use FloatType::*;
797        match dtype {
798            F32 => match self {
799                Self::F64(f) => Self::F32(f as f32),
800                this => this,
801            },
802            F64 => match self {
803                Self::F32(f) => Self::F64(f as f64),
804                this => this,
805            },
806            Float => self,
807        }
808    }
809
810    fn abs(self) -> Float {
811        match self {
812            Self::F32(f) => Self::F32(f.abs()),
813            Self::F64(f) => Self::F64(f.abs()),
814        }
815    }
816
817    fn exp(self) -> Self::Exp {
818        match self {
819            Self::F32(f) => Self::F32(f.exp()),
820            Self::F64(f) => Self::F64(f.exp()),
821        }
822    }
823
824    fn ln(self) -> Self::Log {
825        match self {
826            Self::F32(f) => f.ln().into(),
827            Self::F64(f) => f.ln().into(),
828        }
829    }
830
831    fn log<N: NumberInstance>(self, base: N) -> Self::Log
832    where
833        Float: From<N>,
834    {
835        match self {
836            Self::F32(f) => f.log(Float::from(base).cast_into()).into(),
837            Self::F64(f) => f.log(Float::from(base).cast_into()).into(),
838        }
839    }
840
841    fn pow(self, exp: Number) -> Self {
842        match self {
843            Self::F64(this) => match exp {
844                Number::Complex(exp) => unimplemented!("{}: {}", ERR_COMPLEX_POWER, exp),
845                exp => this.pow(f64::cast_from(exp)).into(),
846            },
847            Self::F32(this) => match exp {
848                Number::Complex(exp) => unimplemented!("{}: {}", ERR_COMPLEX_POWER, exp),
849                Number::Float(Float::F64(exp)) => Self::F64(f64::from(self).pow(exp)),
850                exp => this.pow(f32::cast_from(exp)).into(),
851            },
852        }
853    }
854
855    fn round(self) -> Self::Round {
856        match self {
857            Self::F32(f) => (f.round() as i32).into(),
858            Self::F64(f) => (f.round() as i64).into(),
859        }
860    }
861}
862
863impl RealInstance for Float {
864    const ONE: Self = Float::F32(1.);
865    const ZERO: Self = Float::F32(0.);
866}
867
868impl FloatInstance for Float {
869    fn is_infinite(&self) -> bool {
870        match self {
871            Self::F32(f) => f.is_infinite(),
872            Self::F64(f) => f.is_infinite(),
873        }
874    }
875
876    fn is_nan(&self) -> bool {
877        match self {
878            Self::F32(f) => f.is_nan(),
879            Self::F64(f) => f.is_nan(),
880        }
881    }
882}
883
884impl Eq for Float {}
885
886impl Add for Float {
887    type Output = Self;
888
889    fn add(self, other: Float) -> Self {
890        match (self, other) {
891            (Self::F32(l), Self::F32(r)) => Self::F32(l + r),
892            (Self::F64(l), Self::F64(r)) => Self::F64(l + r),
893            (Self::F64(l), Self::F32(r)) => Self::F64(l + r as f64),
894            (l, r) => r + l,
895        }
896    }
897}
898
899impl AddAssign for Float {
900    fn add_assign(&mut self, other: Self) {
901        let sum = *self + other;
902        *self = sum;
903    }
904}
905
906impl Sub for Float {
907    type Output = Self;
908
909    fn sub(self, other: Float) -> Self {
910        match (self, other) {
911            (Self::F32(l), Self::F32(r)) => Self::F32(l - r),
912            (l, r) => {
913                let l: f64 = l.into();
914                let r: f64 = r.into();
915                Self::F64(l - r)
916            }
917        }
918    }
919}
920
921impl SubAssign for Float {
922    fn sub_assign(&mut self, other: Self) {
923        let diff = *self - other;
924        *self = diff;
925    }
926}
927
928impl Sum for Float {
929    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
930        let mut sum = FloatType::Float.zero();
931        for i in iter {
932            sum += i;
933        }
934        sum
935    }
936}
937
938impl Rem for Float {
939    type Output = Self;
940
941    fn rem(self, other: Self) -> Self::Output {
942        match (self, other) {
943            (Self::F64(l), Self::F64(r)) => Self::F64(l % r),
944            (Self::F32(l), Self::F32(r)) => Self::F32(l % r),
945            (Self::F64(l), Self::F32(r)) => Self::F64(l % r as f64),
946            (Self::F32(l), Self::F64(r)) => Self::F64(l as f64 % r),
947        }
948    }
949}
950
951impl RemAssign for Float {
952    fn rem_assign(&mut self, other: Self) {
953        let rem = *self % other;
954        *self = rem;
955    }
956}
957
958impl Mul for Float {
959    type Output = Self;
960
961    fn mul(self, other: Float) -> Self {
962        match (self, other) {
963            (Self::F32(l), Self::F32(r)) => Self::F32(l * r),
964            (Self::F64(l), Self::F64(r)) => Self::F64(l * r),
965            (Self::F64(l), Self::F32(r)) => Self::F64(l * r as f64),
966            (l, r) => r * l,
967        }
968    }
969}
970
971impl MulAssign for Float {
972    fn mul_assign(&mut self, other: Self) {
973        let product = *self * other;
974        *self = product;
975    }
976}
977
978impl Div for Float {
979    type Output = Self;
980
981    fn div(self, other: Self) -> Self::Output {
982        match (self, other) {
983            (Self::F32(l), Self::F32(r)) => Self::F32(l / r),
984            (Self::F64(l), Self::F64(r)) => Self::F64(l / r),
985            (Self::F32(l), Self::F64(r)) => Self::F64((l as f64) / r),
986            (Self::F64(l), Self::F32(r)) => Self::F64(l / (r as f64)),
987        }
988    }
989}
990
991impl DivAssign for Float {
992    fn div_assign(&mut self, other: Self) {
993        let div = *self / other;
994        *self = div;
995    }
996}
997
998impl Product for Float {
999    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1000        let zero = FloatType::Float.zero();
1001        let mut product = FloatType::Float.one();
1002
1003        for i in iter {
1004            if i == zero {
1005                return zero;
1006            }
1007
1008            product *= i;
1009        }
1010        product
1011    }
1012}
1013
1014macro_rules! trig_float {
1015    ($fun:ident) => {
1016        fn $fun(self) -> Self {
1017            match self {
1018                Float::F32(f) => f.$fun().into(),
1019                Float::F64(f) => f.$fun().into(),
1020            }
1021        }
1022    };
1023}
1024
1025impl Trigonometry for Float {
1026    type Out = Self;
1027
1028    trig_float! {asin}
1029    trig_float! {sin}
1030    trig_float! {sinh}
1031    trig_float! {asinh}
1032
1033    trig_float! {acos}
1034    trig_float! {cos}
1035    trig_float! {cosh}
1036    trig_float! {acosh}
1037
1038    trig_float! {atan}
1039    trig_float! {tan}
1040    trig_float! {tanh}
1041    trig_float! {atanh}
1042}
1043
1044impl Hash for Float {
1045    fn hash<H: Hasher>(&self, state: &mut H) {
1046        super::normalized_f32_bits(f32::cast_from(*self)).hash(state);
1047    }
1048}
1049
1050impl PartialEq for Float {
1051    fn eq(&self, other: &Self) -> bool {
1052        super::normalized_f32_bits(f32::cast_from(*self))
1053            == super::normalized_f32_bits(f32::cast_from(*other))
1054    }
1055}
1056
1057impl PartialOrd for Float {
1058    fn partial_cmp(&self, other: &Float) -> Option<Ordering> {
1059        match (self, other) {
1060            (Float::F32(l), Float::F32(r)) => l.partial_cmp(r),
1061            (Float::F64(l), Float::F64(r)) => l.partial_cmp(r),
1062            (l, r) => f64::from(*l).partial_cmp(&f64::from(*r)),
1063        }
1064    }
1065}
1066
1067impl Default for Float {
1068    fn default() -> Float {
1069        Float::F32(f32::default())
1070    }
1071}
1072
1073impl From<Boolean> for Float {
1074    fn from(b: Boolean) -> Self {
1075        match b {
1076            Boolean(true) => Self::F32(1.0f32),
1077            Boolean(false) => Self::F32(0.0f32),
1078        }
1079    }
1080}
1081
1082impl From<f32> for Float {
1083    fn from(f: f32) -> Self {
1084        Self::F32(f)
1085    }
1086}
1087
1088impl From<f64> for Float {
1089    fn from(f: f64) -> Self {
1090        Self::F64(f)
1091    }
1092}
1093
1094impl From<Int> for Float {
1095    fn from(i: Int) -> Self {
1096        match i {
1097            Int::I8(i) => Self::F32(i as f32),
1098            Int::I64(i) => Self::F64(i as f64),
1099            Int::I32(i) => Self::F32(i as f32),
1100            Int::I16(i) => Self::F32(i as f32),
1101        }
1102    }
1103}
1104
1105impl From<UInt> for Float {
1106    fn from(u: UInt) -> Self {
1107        match u {
1108            UInt::U64(u) => Self::F64(u as f64),
1109            UInt::U32(u) => Self::F32(u as f32),
1110            UInt::U16(u) => Self::F32(u as f32),
1111            UInt::U8(u) => Self::F32(u as f32),
1112        }
1113    }
1114}
1115
1116impl FromStr for Float {
1117    type Err = Error;
1118
1119    fn from_str(s: &str) -> Result<Self, Self::Err> {
1120        f64::from_str(s).map(Self::from).map_err(Error::new)
1121    }
1122}
1123
1124impl CastFrom<Complex> for Float {
1125    fn cast_from(c: Complex) -> Float {
1126        use Complex::*;
1127        match c {
1128            C32(c) => Self::F32(c.re),
1129            C64(c) => Self::F64(c.re),
1130        }
1131    }
1132}
1133
1134impl CastFrom<Float> for Boolean {
1135    fn cast_from(f: Float) -> Boolean {
1136        use Float::*;
1137        Boolean(!matches!(f, F32(0f32) | F64(0f64)))
1138    }
1139}
1140
1141impl CastFrom<Float> for f32 {
1142    fn cast_from(f: Float) -> f32 {
1143        match f {
1144            Float::F32(f) => f,
1145            Float::F64(f) => f as f32,
1146        }
1147    }
1148}
1149
1150impl From<Float> for f64 {
1151    fn from(f: Float) -> f64 {
1152        match f {
1153            Float::F32(f) => f as f64,
1154            Float::F64(f) => f,
1155        }
1156    }
1157}
1158
1159fmt_debug!(Float);
1160
1161impl fmt::Display for Float {
1162    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1163        match self {
1164            Float::F32(n) => fmt::Display::fmt(n, f),
1165            Float::F64(n) => fmt::Display::fmt(n, f),
1166        }
1167    }
1168}
1169
1170#[derive(Copy, Clone, Default, Eq, PartialEq)]
1171struct F32Collator;
1172
1173impl Collate for F32Collator {
1174    type Value = f32;
1175
1176    fn cmp(&self, left: &f32, right: &f32) -> Ordering {
1177        if left == right {
1178            Ordering::Equal
1179        } else {
1180            left.total_cmp(right)
1181        }
1182    }
1183}
1184
1185#[derive(Copy, Clone, Default, Eq, PartialEq)]
1186struct F64Collator;
1187
1188impl Collate for F64Collator {
1189    type Value = f64;
1190
1191    fn cmp(&self, left: &f64, right: &f64) -> Ordering {
1192        if left == right {
1193            Ordering::Equal
1194        } else {
1195            left.total_cmp(right)
1196        }
1197    }
1198}
1199
1200/// Defines a collation order for [`Float`].
1201#[derive(Copy, Clone, Default, Eq, PartialEq)]
1202pub struct FloatCollator {
1203    f32: F32Collator,
1204    f64: F64Collator,
1205}
1206
1207impl Collate for FloatCollator {
1208    type Value = Float;
1209
1210    fn cmp(&self, left: &Self::Value, right: &Self::Value) -> Ordering {
1211        if let Some(order) = left.partial_cmp(right) {
1212            order
1213        } else {
1214            match (left, right) {
1215                (Float::F32(l), Float::F32(r)) => self.f32.cmp(l, r),
1216                (Float::F64(l), Float::F64(r)) => self.f64.cmp(l, r),
1217                (l, r) => self.f64.cmp(&(*l).cast_into(), &(*r).cast_into()),
1218            }
1219        }
1220    }
1221}
1222
1223/// A signed integer.
1224#[derive(Clone, Copy, get_size_derive::GetSize)]
1225pub enum Int {
1226    I8(i8),
1227    I16(i16),
1228    I32(i32),
1229    I64(i64),
1230}
1231
1232impl NumberInstance for Int {
1233    type Abs = Self;
1234    type Exp = Float;
1235    type Log = Float;
1236    type Round = Self;
1237    type Class = IntType;
1238
1239    fn class(&self) -> IntType {
1240        match self {
1241            Self::I8(_) => IntType::I8,
1242            Self::I16(_) => IntType::I16,
1243            Self::I32(_) => IntType::I32,
1244            Self::I64(_) => IntType::I64,
1245        }
1246    }
1247
1248    fn into_type(self, dtype: IntType) -> Int {
1249        use IntType::*;
1250        match dtype {
1251            I8 => match self {
1252                Self::I16(i) => Self::I8(i as i8),
1253                Self::I32(i) => Self::I8(i as i8),
1254                Self::I64(i) => Self::I8(i as i8),
1255                this => this,
1256            },
1257            I16 => match self {
1258                Self::I8(i) => Self::I16(i as i16),
1259                Self::I32(i) => Self::I16(i as i16),
1260                Self::I64(i) => Self::I16(i as i16),
1261                this => this,
1262            },
1263            I32 => match self {
1264                Self::I8(i) => Self::I32(i as i32),
1265                Self::I16(i) => Self::I32(i as i32),
1266                Self::I64(i) => Self::I32(i as i32),
1267                this => this,
1268            },
1269            I64 => match self {
1270                Self::I8(i) => Self::I64(i as i64),
1271                Self::I16(i) => Self::I64(i as i64),
1272                Self::I32(i) => Self::I64(i as i64),
1273                this => this,
1274            },
1275            Int => self,
1276        }
1277    }
1278
1279    fn abs(self) -> Self {
1280        match self {
1281            Self::I8(i) => Int::I8(i.abs()),
1282            Self::I16(i) => Int::I16(i.abs()),
1283            Self::I32(i) => Int::I32(i.abs()),
1284            Self::I64(i) => Int::I64(i.abs()),
1285        }
1286    }
1287
1288    fn exp(self) -> Self::Exp {
1289        Float::from(self).exp()
1290    }
1291
1292    fn ln(self) -> Self::Log {
1293        Float::from(self).ln()
1294    }
1295
1296    fn log<N: NumberInstance>(self, base: N) -> Self::Log
1297    where
1298        Float: From<N>,
1299    {
1300        let this: Float = self.into();
1301        this.log(base)
1302    }
1303
1304    fn pow(self, exp: Number) -> Self {
1305        if exp < exp.class().zero() {
1306            return self.class().zero();
1307        }
1308
1309        match self {
1310            Self::I8(this) => Self::I8(this.pow(exp.cast_into())),
1311            Self::I16(this) => Self::I16(this.pow(exp.cast_into())),
1312            Self::I32(this) => Self::I32(this.pow(exp.cast_into())),
1313            Self::I64(this) => Self::I64(this.pow(exp.cast_into())),
1314        }
1315    }
1316
1317    fn round(self) -> Self::Round {
1318        self
1319    }
1320}
1321
1322impl RealInstance for Int {
1323    const ONE: Self = Int::I8(1);
1324    const ZERO: Self = Int::I8(0);
1325}
1326
1327impl CastFrom<Complex> for Int {
1328    fn cast_from(c: Complex) -> Int {
1329        use Complex::*;
1330        match c {
1331            C32(c) => Self::I32(c.re as i32),
1332            C64(c) => Self::I64(c.re as i64),
1333        }
1334    }
1335}
1336
1337impl CastFrom<Float> for Int {
1338    fn cast_from(f: Float) -> Int {
1339        use Float::*;
1340        match f {
1341            F32(f) => Self::I32(f as i32),
1342            F64(f) => Self::I64(f as i64),
1343        }
1344    }
1345}
1346
1347impl CastFrom<Int> for Boolean {
1348    fn cast_from(i: Int) -> Boolean {
1349        use Int::*;
1350        Boolean(!matches!(i, I8(0) | I16(0) | I32(0) | I64(0)))
1351    }
1352}
1353
1354impl CastFrom<Int> for i8 {
1355    fn cast_from(i: Int) -> i8 {
1356        match i {
1357            Int::I8(i) => i,
1358            Int::I16(i) => i as i8,
1359            Int::I32(i) => i as i8,
1360            Int::I64(i) => i as i8,
1361        }
1362    }
1363}
1364
1365impl CastFrom<Int> for i16 {
1366    fn cast_from(i: Int) -> i16 {
1367        match i {
1368            Int::I8(i) => i as i16,
1369            Int::I16(i) => i,
1370            Int::I32(i) => i as i16,
1371            Int::I64(i) => i as i16,
1372        }
1373    }
1374}
1375
1376impl CastFrom<Int> for i32 {
1377    fn cast_from(i: Int) -> i32 {
1378        match i {
1379            Int::I8(i) => i as i32,
1380            Int::I16(i) => i as i32,
1381            Int::I32(i) => i,
1382            Int::I64(i) => i as i32,
1383        }
1384    }
1385}
1386
1387impl Eq for Int {}
1388
1389impl Add for Int {
1390    type Output = Self;
1391
1392    fn add(self, other: Int) -> Self {
1393        match (self, other) {
1394            (Self::I64(l), Self::I64(r)) => Self::I64(l + r),
1395            (Self::I64(l), Self::I32(r)) => Self::I64(l + r as i64),
1396            (Self::I64(l), Self::I16(r)) => Self::I64(l + r as i64),
1397            (Self::I64(l), Self::I8(r)) => Self::I64(l + r as i64),
1398            (Self::I32(l), Self::I32(r)) => Self::I32(l + r),
1399            (Self::I32(l), Self::I16(r)) => Self::I32(l + r as i32),
1400            (Self::I32(l), Self::I8(r)) => Self::I32(l + r as i32),
1401            (Self::I16(l), Self::I16(r)) => Self::I16(l + r),
1402            (Self::I16(l), Self::I8(r)) => Self::I16(l + r as i16),
1403            (Self::I8(l), Self::I8(r)) => Self::I8(l + r),
1404            (l, r) => r + l,
1405        }
1406    }
1407}
1408
1409impl AddAssign for Int {
1410    fn add_assign(&mut self, other: Self) {
1411        let sum = *self + other;
1412        *self = sum;
1413    }
1414}
1415
1416impl Rem for Int {
1417    type Output = Self;
1418
1419    fn rem(self, other: Self) -> Self::Output {
1420        match (self, other) {
1421            (Self::I64(l), Self::I64(r)) => Self::I64(l % r),
1422            (Self::I64(l), Self::I32(r)) => Self::I64(l % r as i64),
1423            (Self::I64(l), Self::I16(r)) => Self::I64(l % r as i64),
1424            (Self::I64(l), Self::I8(r)) => Self::I64(l % r as i64),
1425            (Self::I32(l), Self::I64(r)) => Self::I64(l as i64 % r),
1426            (Self::I32(l), Self::I32(r)) => Self::I32(l % r),
1427            (Self::I32(l), Self::I16(r)) => Self::I32(l % r as i32),
1428            (Self::I32(l), Self::I8(r)) => Self::I32(l % r as i32),
1429            (Self::I16(l), Self::I64(r)) => Self::I64(l as i64 % r),
1430            (Self::I16(l), Self::I32(r)) => Self::I32(l as i32 % r),
1431            (Self::I16(l), Self::I16(r)) => Self::I16(l % r),
1432            (Self::I16(l), Self::I8(r)) => Self::I16(l % r as i16),
1433            (Self::I8(l), Self::I64(r)) => Self::I64(l as i64 % r),
1434            (Self::I8(l), Self::I32(r)) => Self::I32(l as i32 % r),
1435            (Self::I8(l), Self::I16(r)) => Self::I16(l as i16 % r),
1436            (Self::I8(l), Self::I8(r)) => Self::I8(l % r),
1437        }
1438    }
1439}
1440
1441impl RemAssign for Int {
1442    fn rem_assign(&mut self, other: Self) {
1443        let rem = *self % other;
1444        *self = rem;
1445    }
1446}
1447
1448impl Sub for Int {
1449    type Output = Self;
1450
1451    fn sub(self, other: Int) -> Self {
1452        match (self, other) {
1453            (Self::I64(l), Self::I64(r)) => Self::I64(l - r),
1454            (Self::I64(l), Self::I32(r)) => Self::I64(l - r as i64),
1455            (Self::I64(l), Self::I16(r)) => Self::I64(l - r as i64),
1456            (Self::I64(l), Self::I8(r)) => Self::I64(l - r as i64),
1457            (Self::I32(l), Self::I64(r)) => Self::I64(l as i64 - r),
1458            (Self::I32(l), Self::I32(r)) => Self::I32(l - r),
1459            (Self::I32(l), Self::I16(r)) => Self::I32(l - r as i32),
1460            (Self::I32(l), Self::I8(r)) => Self::I32(l - r as i32),
1461            (Self::I16(l), Self::I64(r)) => Self::I64(l as i64 - r),
1462            (Self::I16(l), Self::I32(r)) => Self::I32(l as i32 - r),
1463            (Self::I16(l), Self::I16(r)) => Self::I16(l - r),
1464            (Self::I16(l), Self::I8(r)) => Self::I16(l - r as i16),
1465            (Self::I8(l), Self::I64(r)) => Self::I64(l as i64 - r),
1466            (Self::I8(l), Self::I32(r)) => Self::I32(l as i32 - r),
1467            (Self::I8(l), Self::I16(r)) => Self::I16(l as i16 - r),
1468            (Self::I8(l), Self::I8(r)) => Self::I8(l - r),
1469        }
1470    }
1471}
1472
1473impl SubAssign for Int {
1474    fn sub_assign(&mut self, other: Self) {
1475        let diff = *self - other;
1476        *self = diff;
1477    }
1478}
1479
1480impl Sum for Int {
1481    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1482        let mut sum = IntType::Int.zero();
1483        for i in iter {
1484            sum += i;
1485        }
1486        sum
1487    }
1488}
1489
1490impl Mul for Int {
1491    type Output = Self;
1492
1493    fn mul(self, other: Int) -> Self {
1494        match (self, other) {
1495            (Self::I64(l), Self::I64(r)) => Self::I64(l * r),
1496            (Self::I64(l), Self::I32(r)) => Self::I64(l * r as i64),
1497            (Self::I64(l), Self::I16(r)) => Self::I64(l * r as i64),
1498            (Self::I32(l), Self::I32(r)) => Self::I32(l * r),
1499            (Self::I32(l), Self::I16(r)) => Self::I32(l * r as i32),
1500            (Self::I16(l), Self::I16(r)) => Self::I16(l * r),
1501            (l, r) => r * l,
1502        }
1503    }
1504}
1505
1506impl MulAssign for Int {
1507    fn mul_assign(&mut self, other: Self) {
1508        let product = *self * other;
1509        *self = product;
1510    }
1511}
1512
1513impl Div for Int {
1514    type Output = Self;
1515
1516    fn div(self, other: Int) -> Self {
1517        match (self, other) {
1518            (Self::I64(l), Self::I64(r)) => Self::I64(l / r),
1519            (Self::I64(l), Self::I32(r)) => Self::I64(l / r as i64),
1520            (Self::I64(l), Self::I16(r)) => Self::I64(l / r as i64),
1521            (Self::I64(l), Self::I8(r)) => Self::I64(l / r as i64),
1522
1523            (Self::I32(l), Self::I64(r)) => Self::I64(l as i64 / r),
1524            (Self::I32(l), Self::I32(r)) => Self::I32(l / r),
1525            (Self::I32(l), Self::I16(r)) => Self::I32(l / r as i32),
1526            (Self::I32(l), Self::I8(r)) => Self::I32(l / r as i32),
1527
1528            (Self::I16(l), Self::I64(r)) => Self::I64(l as i64 / r),
1529            (Self::I16(l), Self::I32(r)) => Self::I32(l as i32 / r),
1530            (Self::I16(l), Self::I16(r)) => Self::I16(l / r),
1531            (Self::I16(l), Self::I8(r)) => Self::I16(l / r as i16),
1532
1533            (Self::I8(l), Self::I64(r)) => Self::I64(l as i64 / r),
1534            (Self::I8(l), Self::I32(r)) => Self::I32(l as i32 / r),
1535            (Self::I8(l), Self::I16(r)) => Self::I16(l as i16 / r),
1536            (Self::I8(l), Self::I8(r)) => Self::I8(l / r),
1537        }
1538    }
1539}
1540
1541impl DivAssign for Int {
1542    fn div_assign(&mut self, other: Self) {
1543        let div = *self / other;
1544        *self = div;
1545    }
1546}
1547
1548impl Product for Int {
1549    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1550        let zero = IntType::Int.zero();
1551        let mut product = IntType::Int.one();
1552
1553        for i in iter {
1554            if i == zero {
1555                return zero;
1556            }
1557
1558            product *= i;
1559        }
1560        product
1561    }
1562}
1563
1564macro_rules! trig_int {
1565    ($fun:ident) => {
1566        fn $fun(self) -> Self::Out {
1567            match self {
1568                Self::I8(i) => (i as f32).$fun().into(),
1569                Self::I16(i) => (i as f32).$fun().into(),
1570                Self::I32(i) => (i as f32).$fun().into(),
1571                Self::I64(i) => (i as f64).$fun().into(),
1572            }
1573        }
1574    };
1575}
1576
1577impl Trigonometry for Int {
1578    type Out = Float;
1579
1580    trig_int! {asin}
1581    trig_int! {sin}
1582    trig_int! {sinh}
1583    trig_int! {asinh}
1584
1585    trig_int! {acos}
1586    trig_int! {cos}
1587    trig_int! {cosh}
1588    trig_int! {acosh}
1589
1590    trig_int! {atan}
1591    trig_int! {tan}
1592    trig_int! {tanh}
1593    trig_int! {atanh}
1594}
1595
1596impl PartialEq for Int {
1597    fn eq(&self, other: &Self) -> bool {
1598        match (self, other) {
1599            (Self::I16(l), Self::I16(r)) => l.eq(r),
1600            (Self::I32(l), Self::I32(r)) => l.eq(r),
1601            (Self::I64(l), Self::I64(r)) => l.eq(r),
1602            (Self::I64(l), r) => l.eq(&i64::from(*r)),
1603            (l, r) => i64::from(*l).eq(&i64::from(*r)),
1604        }
1605    }
1606}
1607
1608impl Hash for Int {
1609    fn hash<H: Hasher>(&self, state: &mut H) {
1610        i64::from(*self).hash(state);
1611    }
1612}
1613
1614impl PartialOrd for Int {
1615    fn partial_cmp(&self, other: &Int) -> Option<Ordering> {
1616        Some(self.cmp(other))
1617    }
1618}
1619
1620impl Ord for Int {
1621    fn cmp(&self, other: &Self) -> Ordering {
1622        match (self, other) {
1623            (Int::I8(l), Int::I8(r)) => l.cmp(r),
1624            (Int::I16(l), Int::I16(r)) => l.cmp(r),
1625            (Int::I32(l), Int::I32(r)) => l.cmp(r),
1626            (Int::I64(l), Int::I64(r)) => l.cmp(r),
1627            (l, r) => i64::from(*l).cmp(&i64::from(*r)),
1628        }
1629    }
1630}
1631
1632impl Default for Int {
1633    fn default() -> Int {
1634        Int::I16(i16::default())
1635    }
1636}
1637
1638impl From<i8> for Int {
1639    fn from(i: i8) -> Int {
1640        Int::I8(i)
1641    }
1642}
1643
1644impl From<i16> for Int {
1645    fn from(i: i16) -> Int {
1646        Int::I16(i)
1647    }
1648}
1649
1650impl From<i32> for Int {
1651    fn from(i: i32) -> Int {
1652        Int::I32(i)
1653    }
1654}
1655
1656impl From<i64> for Int {
1657    fn from(i: i64) -> Int {
1658        Int::I64(i)
1659    }
1660}
1661
1662impl From<UInt> for Int {
1663    fn from(u: UInt) -> Int {
1664        match u {
1665            UInt::U64(u) => Int::I64(u as i64),
1666            UInt::U32(u) => Int::I32(u as i32),
1667            UInt::U16(u) => Int::I16(u as i16),
1668            UInt::U8(u) => Int::I16(u as i16),
1669        }
1670    }
1671}
1672
1673impl From<Boolean> for Int {
1674    fn from(b: Boolean) -> Int {
1675        match b {
1676            Boolean(true) => Int::I16(1),
1677            Boolean(false) => Int::I16(0),
1678        }
1679    }
1680}
1681
1682impl From<Int> for i64 {
1683    fn from(i: Int) -> i64 {
1684        match i {
1685            Int::I8(i) => i as i64,
1686            Int::I16(i) => i as i64,
1687            Int::I32(i) => i as i64,
1688            Int::I64(i) => i,
1689        }
1690    }
1691}
1692
1693impl FromStr for Int {
1694    type Err = Error;
1695
1696    fn from_str(s: &str) -> Result<Self, Self::Err> {
1697        i64::from_str(s).map(Self::from).map_err(Error::new)
1698    }
1699}
1700
1701fmt_debug!(Int);
1702
1703impl fmt::Display for Int {
1704    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1705        match self {
1706            Int::I8(i) => fmt::Display::fmt(i, f),
1707            Int::I16(i) => fmt::Display::fmt(i, f),
1708            Int::I32(i) => fmt::Display::fmt(i, f),
1709            Int::I64(i) => fmt::Display::fmt(i, f),
1710        }
1711    }
1712}
1713
1714/// An unsigned integer.
1715#[derive(Clone, Copy, get_size_derive::GetSize)]
1716pub enum UInt {
1717    U8(u8),
1718    U16(u16),
1719    U32(u32),
1720    U64(u64),
1721}
1722
1723impl NumberInstance for UInt {
1724    type Abs = Self;
1725    type Exp = Float;
1726    type Log = Float;
1727    type Round = Self;
1728    type Class = UIntType;
1729
1730    fn class(&self) -> UIntType {
1731        match self {
1732            Self::U8(_) => UIntType::U8,
1733            Self::U16(_) => UIntType::U16,
1734            Self::U32(_) => UIntType::U32,
1735            Self::U64(_) => UIntType::U64,
1736        }
1737    }
1738
1739    fn into_type(self, dtype: UIntType) -> UInt {
1740        use UIntType::*;
1741        match dtype {
1742            U8 => match self {
1743                Self::U16(u) => Self::U8(u as u8),
1744                Self::U32(u) => Self::U8(u as u8),
1745                Self::U64(u) => Self::U8(u as u8),
1746                this => this,
1747            },
1748            U16 => match self {
1749                Self::U8(u) => Self::U16(u as u16),
1750                Self::U32(u) => Self::U16(u as u16),
1751                Self::U64(u) => Self::U16(u as u16),
1752                this => this,
1753            },
1754            U32 => match self {
1755                Self::U8(u) => Self::U32(u as u32),
1756                Self::U16(u) => Self::U32(u as u32),
1757                Self::U64(u) => Self::U32(u as u32),
1758                this => this,
1759            },
1760            U64 => match self {
1761                Self::U8(u) => Self::U64(u as u64),
1762                Self::U16(u) => Self::U64(u as u64),
1763                Self::U32(u) => Self::U64(u as u64),
1764                this => this,
1765            },
1766            UInt => self,
1767        }
1768    }
1769
1770    fn abs(self) -> UInt {
1771        self
1772    }
1773
1774    fn exp(self) -> Self::Exp {
1775        Float::from(self).exp()
1776    }
1777
1778    fn ln(self) -> Self::Log {
1779        Float::from(self).ln()
1780    }
1781
1782    fn log<N: NumberInstance>(self, base: N) -> Self::Log
1783    where
1784        Float: From<N>,
1785    {
1786        let this: Float = self.into();
1787        this.log(base)
1788    }
1789
1790    fn pow(self, exp: Number) -> Self {
1791        if exp < Number::from(0) {
1792            return self.class().zero();
1793        }
1794
1795        match self {
1796            Self::U8(this) => Self::U8(this.pow(exp.cast_into())),
1797            Self::U16(this) => Self::U16(this.pow(exp.cast_into())),
1798            Self::U32(this) => Self::U32(this.pow(exp.cast_into())),
1799            Self::U64(this) => Self::U64(this.pow(exp.cast_into())),
1800        }
1801    }
1802
1803    fn round(self) -> Self::Round {
1804        self
1805    }
1806}
1807
1808impl RealInstance for UInt {
1809    const ONE: Self = UInt::U8(1);
1810    const ZERO: Self = UInt::U8(0);
1811}
1812
1813impl CastFrom<Complex> for UInt {
1814    fn cast_from(c: Complex) -> UInt {
1815        use Complex::*;
1816        match c {
1817            C32(c) => Self::U32(c.re as u32),
1818            C64(c) => Self::U64(c.re as u64),
1819        }
1820    }
1821}
1822
1823impl CastFrom<Float> for UInt {
1824    fn cast_from(f: Float) -> UInt {
1825        use Float::*;
1826        match f {
1827            F32(f) => Self::U32(f as u32),
1828            F64(f) => Self::U64(f as u64),
1829        }
1830    }
1831}
1832
1833impl CastFrom<Int> for UInt {
1834    fn cast_from(i: Int) -> UInt {
1835        use Int::*;
1836        match i {
1837            I8(i) => Self::U8(i as u8),
1838            I16(i) => Self::U16(i as u16),
1839            I32(i) => Self::U32(i as u32),
1840            I64(i) => Self::U64(i as u64),
1841        }
1842    }
1843}
1844
1845impl CastFrom<UInt> for bool {
1846    fn cast_from(u: UInt) -> bool {
1847        use UInt::*;
1848        !matches!(u, U8(0u8) | U16(0u16) | U32(0u32) | U64(0u64))
1849    }
1850}
1851
1852impl CastFrom<UInt> for u8 {
1853    fn cast_from(u: UInt) -> u8 {
1854        use UInt::*;
1855        match u {
1856            U8(u) => u,
1857            U16(u) => u as u8,
1858            U32(u) => u as u8,
1859            U64(u) => u as u8,
1860        }
1861    }
1862}
1863
1864impl CastFrom<UInt> for u16 {
1865    fn cast_from(u: UInt) -> u16 {
1866        use UInt::*;
1867        match u {
1868            U8(u) => u as u16,
1869            U16(u) => u,
1870            U32(u) => u as u16,
1871            U64(u) => u as u16,
1872        }
1873    }
1874}
1875
1876impl CastFrom<UInt> for u32 {
1877    fn cast_from(u: UInt) -> u32 {
1878        use UInt::*;
1879        match u {
1880            U8(u) => u as u32,
1881            U16(u) => u as u32,
1882            U32(u) => u,
1883            U64(u) => u as u32,
1884        }
1885    }
1886}
1887
1888impl Add for UInt {
1889    type Output = Self;
1890
1891    fn add(self, other: UInt) -> Self {
1892        match (self, other) {
1893            (UInt::U64(l), UInt::U64(r)) => UInt::U64(l + r),
1894            (UInt::U64(l), UInt::U32(r)) => UInt::U64(l + r as u64),
1895            (UInt::U64(l), UInt::U16(r)) => UInt::U64(l + r as u64),
1896            (UInt::U64(l), UInt::U8(r)) => UInt::U64(l + r as u64),
1897            (UInt::U32(l), UInt::U32(r)) => UInt::U32(l + r),
1898            (UInt::U32(l), UInt::U16(r)) => UInt::U32(l + r as u32),
1899            (UInt::U32(l), UInt::U8(r)) => UInt::U32(l + r as u32),
1900            (UInt::U16(l), UInt::U16(r)) => UInt::U16(l + r),
1901            (UInt::U16(l), UInt::U8(r)) => UInt::U16(l + r as u16),
1902            (UInt::U8(l), UInt::U8(r)) => UInt::U8(l + r),
1903            (l, r) => r + l,
1904        }
1905    }
1906}
1907
1908impl AddAssign for UInt {
1909    fn add_assign(&mut self, other: Self) {
1910        let sum = *self + other;
1911        *self = sum;
1912    }
1913}
1914
1915impl Rem for UInt {
1916    type Output = Self;
1917
1918    fn rem(self, other: Self) -> Self::Output {
1919        match (self, other) {
1920            (UInt::U64(l), UInt::U64(r)) => UInt::U64(l % r),
1921            (UInt::U64(l), UInt::U32(r)) => UInt::U64(l % r as u64),
1922            (UInt::U64(l), UInt::U16(r)) => UInt::U64(l % r as u64),
1923            (UInt::U64(l), UInt::U8(r)) => UInt::U64(l % r as u64),
1924            (UInt::U32(l), UInt::U32(r)) => UInt::U32(l % r),
1925            (UInt::U32(l), UInt::U16(r)) => UInt::U32(l % r as u32),
1926            (UInt::U32(l), UInt::U8(r)) => UInt::U32(l % r as u32),
1927            (UInt::U16(l), UInt::U16(r)) => UInt::U16(l % r),
1928            (UInt::U16(l), UInt::U8(r)) => UInt::U16(l % r as u16),
1929            (UInt::U8(l), UInt::U8(r)) => UInt::U8(l % r),
1930            (UInt::U8(l), UInt::U16(r)) => UInt::U16(l as u16 % r),
1931            (UInt::U8(l), UInt::U32(r)) => UInt::U32(l as u32 % r),
1932            (UInt::U8(l), UInt::U64(r)) => UInt::U64(l as u64 % r),
1933            (UInt::U16(l), r) => {
1934                let r: u64 = r.into();
1935                UInt::U16(l % r as u16)
1936            }
1937            (UInt::U32(l), r) => {
1938                let r: u64 = r.into();
1939                UInt::U32(l % r as u32)
1940            }
1941        }
1942    }
1943}
1944
1945impl Sub for UInt {
1946    type Output = Self;
1947
1948    fn sub(self, other: UInt) -> Self {
1949        match (self, other) {
1950            (UInt::U64(l), UInt::U64(r)) => UInt::U64(l - r),
1951            (UInt::U64(l), UInt::U32(r)) => UInt::U64(l - r as u64),
1952            (UInt::U64(l), UInt::U16(r)) => UInt::U64(l - r as u64),
1953            (UInt::U64(l), UInt::U8(r)) => UInt::U64(l - r as u64),
1954            (UInt::U32(l), UInt::U32(r)) => UInt::U32(l - r),
1955            (UInt::U32(l), UInt::U16(r)) => UInt::U32(l - r as u32),
1956            (UInt::U32(l), UInt::U8(r)) => UInt::U32(l - r as u32),
1957            (UInt::U16(l), UInt::U16(r)) => UInt::U16(l - r),
1958            (UInt::U16(l), UInt::U8(r)) => UInt::U16(l - r as u16),
1959            (UInt::U8(l), UInt::U8(r)) => UInt::U8(l - r),
1960            (UInt::U8(l), UInt::U16(r)) => UInt::U16(l as u16 - r),
1961            (UInt::U8(l), UInt::U32(r)) => UInt::U32(l as u32 - r),
1962            (UInt::U8(l), UInt::U64(r)) => UInt::U64(l as u64 - r),
1963            (UInt::U16(l), r) => {
1964                let r: u64 = r.into();
1965                UInt::U16(l - r as u16)
1966            }
1967            (UInt::U32(l), r) => {
1968                let r: u64 = r.into();
1969                UInt::U32(l - r as u32)
1970            }
1971        }
1972    }
1973}
1974
1975impl SubAssign for UInt {
1976    fn sub_assign(&mut self, other: Self) {
1977        let diff = *self - other;
1978        *self = diff;
1979    }
1980}
1981
1982impl Sum for UInt {
1983    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1984        let mut sum = UIntType::UInt.zero();
1985        for i in iter {
1986            sum += i;
1987        }
1988        sum
1989    }
1990}
1991
1992impl Mul for UInt {
1993    type Output = Self;
1994
1995    fn mul(self, other: UInt) -> Self {
1996        match (self, other) {
1997            (UInt::U64(l), UInt::U64(r)) => UInt::U64(l * r),
1998            (UInt::U64(l), UInt::U32(r)) => UInt::U64(l * r as u64),
1999            (UInt::U64(l), UInt::U16(r)) => UInt::U64(l * r as u64),
2000            (UInt::U64(l), UInt::U8(r)) => UInt::U64(l * r as u64),
2001            (UInt::U32(l), UInt::U32(r)) => UInt::U32(l * r),
2002            (UInt::U32(l), UInt::U16(r)) => UInt::U32(l * r as u32),
2003            (UInt::U32(l), UInt::U8(r)) => UInt::U32(l * r as u32),
2004            (UInt::U16(l), UInt::U16(r)) => UInt::U16(l * r),
2005            (UInt::U16(l), UInt::U8(r)) => UInt::U16(l * r as u16),
2006            (UInt::U8(l), UInt::U8(r)) => UInt::U8(l * r),
2007            (l, r) => r * l,
2008        }
2009    }
2010}
2011
2012impl MulAssign for UInt {
2013    fn mul_assign(&mut self, other: Self) {
2014        let product = *self * other;
2015        *self = product;
2016    }
2017}
2018
2019impl Div for UInt {
2020    type Output = Self;
2021
2022    fn div(self, other: UInt) -> Self {
2023        match (self, other) {
2024            (UInt::U64(l), UInt::U64(r)) => UInt::U64(l / r),
2025            (UInt::U64(l), UInt::U32(r)) => UInt::U64(l / r as u64),
2026            (UInt::U64(l), UInt::U16(r)) => UInt::U64(l / r as u64),
2027            (UInt::U64(l), UInt::U8(r)) => UInt::U64(l / r as u64),
2028
2029            (UInt::U32(l), UInt::U64(r)) => UInt::U64(l as u64 / r),
2030            (UInt::U32(l), UInt::U32(r)) => UInt::U32(l / r),
2031            (UInt::U32(l), UInt::U16(r)) => UInt::U32(l / r as u32),
2032            (UInt::U32(l), UInt::U8(r)) => UInt::U32(l / r as u32),
2033
2034            (UInt::U16(l), UInt::U64(r)) => UInt::U64(l as u64 / r),
2035            (UInt::U16(l), UInt::U32(r)) => UInt::U32(l as u32 / r),
2036            (UInt::U16(l), UInt::U16(r)) => UInt::U16(l / r),
2037            (UInt::U16(l), UInt::U8(r)) => UInt::U16(l / r as u16),
2038
2039            (UInt::U8(l), UInt::U64(r)) => UInt::U64(l as u64 / r),
2040            (UInt::U8(l), UInt::U32(r)) => UInt::U32(l as u32 / r),
2041            (UInt::U8(l), UInt::U16(r)) => UInt::U16(l as u16 / r),
2042            (UInt::U8(l), UInt::U8(r)) => UInt::U8(l / r),
2043        }
2044    }
2045}
2046
2047impl DivAssign for UInt {
2048    fn div_assign(&mut self, other: Self) {
2049        let div = *self / other;
2050        *self = div;
2051    }
2052}
2053
2054impl Product for UInt {
2055    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
2056        let zero = UIntType::UInt.zero();
2057        let mut product = UIntType::UInt.one();
2058
2059        for i in iter {
2060            if i == zero {
2061                return zero;
2062            }
2063
2064            product *= i;
2065        }
2066        product
2067    }
2068}
2069
2070macro_rules! trig_uint {
2071    ($fun:ident) => {
2072        fn $fun(self) -> Self::Out {
2073            match self {
2074                Self::U8(u) => (u as f32).$fun().into(),
2075                Self::U16(u) => (u as f32).$fun().into(),
2076                Self::U32(u) => (u as f32).$fun().into(),
2077                Self::U64(u) => (u as f64).$fun().into(),
2078            }
2079        }
2080    };
2081}
2082
2083impl Trigonometry for UInt {
2084    type Out = Float;
2085
2086    trig_uint! {asin}
2087    trig_uint! {sin}
2088    trig_uint! {sinh}
2089    trig_uint! {asinh}
2090
2091    trig_uint! {acos}
2092    trig_uint! {cos}
2093    trig_uint! {cosh}
2094    trig_uint! {acosh}
2095
2096    trig_uint! {atan}
2097    trig_uint! {tan}
2098    trig_uint! {tanh}
2099    trig_uint! {atanh}
2100}
2101
2102impl Eq for UInt {}
2103
2104impl PartialEq for UInt {
2105    fn eq(&self, other: &UInt) -> bool {
2106        match (self, other) {
2107            (Self::U8(l), Self::U8(r)) => l.eq(r),
2108            (Self::U16(l), Self::U16(r)) => l.eq(r),
2109            (Self::U32(l), Self::U32(r)) => l.eq(r),
2110            (Self::U64(l), Self::U64(r)) => l.eq(r),
2111            (l, r) => u64::from(*l).eq(&u64::from(*r)),
2112        }
2113    }
2114}
2115
2116impl Hash for UInt {
2117    fn hash<H: Hasher>(&self, state: &mut H) {
2118        u64::from(*self).hash(state);
2119    }
2120}
2121
2122impl PartialOrd for UInt {
2123    fn partial_cmp(&self, other: &UInt) -> Option<Ordering> {
2124        Some(self.cmp(other))
2125    }
2126}
2127
2128impl Ord for UInt {
2129    fn cmp(&self, other: &UInt) -> Ordering {
2130        match (self, other) {
2131            (Self::U8(l), Self::U8(r)) => l.cmp(r),
2132            (Self::U16(l), Self::U16(r)) => l.cmp(r),
2133            (Self::U32(l), Self::U32(r)) => l.cmp(r),
2134            (Self::U64(l), Self::U64(r)) => l.cmp(r),
2135            (l, r) => u64::from(*l).cmp(&u64::from(*r)),
2136        }
2137    }
2138}
2139
2140impl Default for UInt {
2141    fn default() -> UInt {
2142        UInt::U8(u8::default())
2143    }
2144}
2145
2146impl From<Boolean> for UInt {
2147    fn from(b: Boolean) -> UInt {
2148        match b {
2149            Boolean(true) => UInt::U8(1),
2150            Boolean(false) => UInt::U8(0),
2151        }
2152    }
2153}
2154
2155impl From<u8> for UInt {
2156    fn from(u: u8) -> UInt {
2157        UInt::U8(u)
2158    }
2159}
2160
2161impl From<u16> for UInt {
2162    fn from(u: u16) -> UInt {
2163        UInt::U16(u)
2164    }
2165}
2166
2167impl From<u32> for UInt {
2168    fn from(u: u32) -> UInt {
2169        UInt::U32(u)
2170    }
2171}
2172
2173impl From<u64> for UInt {
2174    fn from(u: u64) -> UInt {
2175        UInt::U64(u)
2176    }
2177}
2178
2179impl From<UInt> for u64 {
2180    fn from(u: UInt) -> u64 {
2181        match u {
2182            UInt::U64(u) => u,
2183            UInt::U32(u) => u as u64,
2184            UInt::U16(u) => u as u64,
2185            UInt::U8(u) => u as u64,
2186        }
2187    }
2188}
2189
2190impl From<UInt> for usize {
2191    fn from(u: UInt) -> usize {
2192        match u {
2193            UInt::U64(u) => u as usize,
2194            UInt::U32(u) => u as usize,
2195            UInt::U16(u) => u as usize,
2196            UInt::U8(u) => u as usize,
2197        }
2198    }
2199}
2200
2201impl FromStr for UInt {
2202    type Err = Error;
2203
2204    fn from_str(s: &str) -> Result<Self, Self::Err> {
2205        u64::from_str(s).map(Self::from).map_err(Error::new)
2206    }
2207}
2208
2209fmt_debug!(UInt);
2210
2211impl fmt::Display for UInt {
2212    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2213        match self {
2214            UInt::U8(u) => fmt::Display::fmt(u, f),
2215            UInt::U16(u) => fmt::Display::fmt(u, f),
2216            UInt::U32(u) => fmt::Display::fmt(u, f),
2217            UInt::U64(u) => fmt::Display::fmt(u, f),
2218        }
2219    }
2220}