arr_rs/numeric/types/
numeric.rs1use 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
9pub trait Numeric: ArrayElement + Clone + Copy + Display + Debug + PartialEq + PartialOrd + FromStr {
11
12 fn rand(range: RangeInclusive<Self>) -> Self;
14
15 fn from<U: Numeric>(value: U) -> Self {
17 Self::from_f64(value.to_f64())
18 }
19
20 fn from_usize(value: usize) -> Self;
22
23 fn from_f64(value: f64) -> Self;
25
26 fn to_usize(&self) -> usize;
28
29 fn to_isize(&self) -> isize;
31
32 fn to_i32(&self) -> i32;
34
35 fn to_f64(&self) -> f64;
37
38 fn is_inf(&self) -> bool;
40
41 #[must_use]
43 fn max(&self) -> Self;
44
45 #[must_use]
47 fn bitwise_and(&self, other: &Self) -> Self;
48
49 #[must_use]
51 fn bitwise_or(&self, other: &Self) -> Self;
52
53 #[must_use]
55 fn bitwise_xor(&self, other: &Self) -> Self;
56
57 #[must_use]
59 fn bitwise_not(&self) -> Self;
60
61 #[must_use]
63 fn left_shift(&self, other: &Self) -> Self;
64
65 #[must_use]
67 fn right_shift(&self, other: &Self) -> Self;
68
69 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);