arr_rs/numeric/types/
numeric.rs

1use std::fmt::{Debug, Display};
2use std::i64;
3use std::ops::RangeInclusive;
4use std::str::FromStr;
5use rand::{Rng, distributions::Uniform};
6
7use crate::core::types::ArrayElement;
8
9/// Numeric type for array
10pub trait Numeric: ArrayElement + Clone + Copy + Display + Debug + PartialEq + PartialOrd + FromStr {
11
12    /// Generate random value
13    fn rand(range: RangeInclusive<Self>) -> Self;
14
15    /// Convert from any other numeric
16    fn from<U: Numeric>(value: U) -> Self {
17        Self::from_f64(value.to_f64())
18    }
19
20    /// Convert from usize
21    fn from_usize(value: usize) -> Self;
22
23    /// Convert from f64
24    fn from_f64(value: f64) -> Self;
25
26    /// Convert to usize
27    fn to_usize(&self) -> usize;
28
29    /// Convert to isize
30    fn to_isize(&self) -> isize;
31
32    /// Convert to i32
33    fn to_i32(&self) -> i32;
34
35    /// Convert to f64
36    fn to_f64(&self) -> f64;
37
38    /// Check if is infinity
39    fn is_inf(&self) -> bool;
40
41    /// Get max value for type
42    #[must_use]
43    fn max(&self) -> Self;
44
45    /// bitwise and operation
46    #[must_use]
47    fn bitwise_and(&self, other: &Self) -> Self;
48
49    /// bitwise or operation
50    #[must_use]
51    fn bitwise_or(&self, other: &Self) -> Self;
52
53    /// bitwise xor operation
54    #[must_use]
55    fn bitwise_xor(&self, other: &Self) -> Self;
56
57    /// bitwise not operation
58    #[must_use]
59    fn bitwise_not(&self) -> Self;
60
61    /// left shift operation
62    #[must_use]
63    fn left_shift(&self, other: &Self) -> Self;
64
65    /// right shift operation
66    #[must_use]
67    fn right_shift(&self, other: &Self) -> Self;
68
69    /// binary representation of number
70    fn binary_repr(&self) -> String;
71}
72
73macro_rules! impl_numeric {
74    ($t:ty) => {
75        impl ArrayElement for $t {
76
77            fn zero() -> Self {
78                0 as $t
79            }
80
81            fn one() -> Self {
82                1 as $t
83            }
84
85            fn is_nan(&self) -> bool {
86                false
87            }
88        }
89
90        impl Numeric for $t {
91
92            fn rand(range: RangeInclusive<Self>) -> $t {
93                let mut rng = rand::thread_rng();
94                let value = rng.sample(&Uniform::from(range));
95                value as $t
96            }
97
98            fn from_usize(value: usize) -> $t {
99                value as $t
100            }
101
102            fn from_f64(value: f64) -> $t {
103                value as $t
104            }
105
106            fn to_usize(&self) -> usize {
107                *self as usize
108            }
109
110            fn to_isize(&self) -> isize {
111                *self as isize
112            }
113
114            fn to_i32(&self) -> i32 {
115                *self as i32
116            }
117
118            fn to_f64(&self) -> f64 {
119                *self as f64
120            }
121
122            fn is_inf(&self) -> bool {
123                false
124            }
125
126            fn max(&self) -> Self {
127                <$t>::MAX
128            }
129
130            fn bitwise_and(&self, other: &Self) -> Self {
131                self & other
132            }
133
134            fn bitwise_or(&self, other: &Self) -> Self {
135                self | other
136            }
137
138            fn bitwise_xor(&self, other: &Self) -> Self {
139                self ^ other
140            }
141
142            fn bitwise_not(&self) -> Self {
143                !self.clone()
144            }
145
146            fn left_shift(&self, other: &Self) -> Self {
147                self << other
148            }
149
150            fn right_shift(&self, other: &Self) -> Self {
151                self >> other
152            }
153
154            fn binary_repr(&self) -> String {
155                format!("{self:b}")
156            }
157        }
158    };
159}
160impl_numeric!(isize);
161impl_numeric!(i8);
162impl_numeric!(i16);
163impl_numeric!(i32);
164impl_numeric!(i64);
165impl_numeric!(usize);
166impl_numeric!(u8);
167impl_numeric!(u16);
168impl_numeric!(u32);
169impl_numeric!(u64);
170
171macro_rules! impl_numeric_float {
172    ($t:ty, $ti:ty) => {
173        impl ArrayElement for $t {
174
175            fn zero() -> Self {
176                0 as $t
177            }
178
179            fn one() -> Self {
180                1 as $t
181            }
182
183            fn is_nan(&self) -> bool {
184                <$t>::is_nan(*self)
185            }
186        }
187
188        impl Numeric for $t {
189
190            fn rand(range: RangeInclusive<Self>) -> $t {
191                let mut rng = rand::thread_rng();
192                let value = rng.sample(&Uniform::from(range));
193                value as $t
194            }
195
196            fn from_usize(value: usize) -> $t {
197                value as $t
198            }
199
200            fn from_f64(value: f64) -> $t {
201                value as $t
202            }
203
204            fn to_usize(&self) -> usize {
205                *self as usize
206            }
207
208            fn to_isize(&self) -> isize {
209                *self as isize
210            }
211
212            fn to_i32(&self) -> i32 {
213                *self as i32
214            }
215
216            fn to_f64(&self) -> f64 {
217                *self as f64
218            }
219
220            fn is_inf(&self) -> bool {
221                <$t>::is_infinite(*self)
222            }
223
224            fn max(&self) -> Self {
225                <$t>::MAX
226            }
227
228            fn bitwise_and(&self, other: &Self) -> Self {
229                (*self as $ti & *other as $ti) as $t
230            }
231
232            fn bitwise_or(&self, other: &Self) -> Self {
233                (*self as $ti | *other as $ti) as $t
234            }
235
236            fn bitwise_xor(&self, other: &Self) -> Self {
237                (*self as $ti ^ *other as $ti) as $t
238            }
239
240            fn bitwise_not(&self) -> Self {
241                !(*self as $ti) as $t
242            }
243
244            fn left_shift(&self, other: &Self) -> Self {
245                ((*self as $ti) << (*other as $ti)) as $t
246            }
247
248            fn right_shift(&self, other: &Self) -> Self {
249                ((*self as $ti) >> (*other as $ti)) as $t
250            }
251
252            fn binary_repr(&self) -> String {
253                format!("{:b}", *self as $ti)
254            }
255        }
256    };
257}
258
259impl_numeric_float!(f32, i64);
260impl_numeric_float!(f64, i128);