deepcl_common/float/
relaxed.rs1use core::f32;
2use core::{
3 cmp::Ordering,
4 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
5};
6
7use bytemuck::{Pod, Zeroable};
8use derive_more::Display;
9use num_traits::{Num, NumCast, One, ToPrimitive, Zero};
10
11#[allow(non_camel_case_types)]
14#[repr(transparent)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[derive(Clone, Copy, Default, Zeroable, Pod, PartialEq, PartialOrd, Debug, Display)]
17pub struct flex32(f32);
18
19impl flex32 {
20 pub const MIN_POSITIVE: Self = Self(half::f16::MIN_POSITIVE.to_f32_const());
22
23 pub const fn from_f32(val: f32) -> Self {
25 flex32(val)
26 }
27
28 pub const fn from_f64(val: f64) -> Self {
30 flex32(val as f32)
31 }
32
33 pub const fn to_f32(self) -> f32 {
35 self.0
36 }
37
38 pub const fn to_f64(self) -> f64 {
40 self.0 as f64
41 }
42
43 pub fn total_cmp(&self, other: &flex32) -> Ordering {
45 self.0.total_cmp(&other.0)
46 }
47
48 pub fn is_nan(&self) -> bool {
50 self.0.is_nan()
51 }
52}
53
54impl Add for flex32 {
55 type Output = Self;
56
57 fn add(self, other: Self) -> Self {
58 flex32(self.0 + other.0)
59 }
60}
61
62impl Sub for flex32 {
63 type Output = Self;
64
65 fn sub(self, other: Self) -> Self {
66 flex32(self.0 - other.0)
67 }
68}
69
70impl Neg for flex32 {
71 type Output = Self;
72
73 fn neg(self) -> Self {
74 flex32(-self.0)
75 }
76}
77
78impl AddAssign for flex32 {
79 fn add_assign(&mut self, other: Self) {
80 self.0 += other.0;
81 }
82}
83
84impl SubAssign for flex32 {
85 fn sub_assign(&mut self, other: Self) {
86 self.0 -= other.0;
87 }
88}
89
90impl Mul for flex32 {
91 type Output = flex32;
92
93 fn mul(self, rhs: Self) -> Self::Output {
94 flex32(self.0 * rhs.0)
95 }
96}
97
98impl Div for flex32 {
99 type Output = flex32;
100
101 fn div(self, rhs: Self) -> Self::Output {
102 flex32(self.0 / rhs.0)
103 }
104}
105
106impl Rem for flex32 {
107 type Output = flex32;
108
109 fn rem(self, rhs: Self) -> Self::Output {
110 flex32(self.0 % rhs.0)
111 }
112}
113
114impl MulAssign for flex32 {
115 fn mul_assign(&mut self, rhs: Self) {
116 self.0 *= rhs.0;
117 }
118}
119
120impl DivAssign for flex32 {
121 fn div_assign(&mut self, rhs: Self) {
122 self.0 /= rhs.0;
123 }
124}
125
126impl RemAssign for flex32 {
127 fn rem_assign(&mut self, rhs: Self) {
128 self.0 %= rhs.0;
129 }
130}
131
132impl From<f32> for flex32 {
133 fn from(value: f32) -> Self {
134 Self::from_f32(value)
135 }
136}
137
138impl From<flex32> for f32 {
139 fn from(val: flex32) -> Self {
140 val.to_f32()
141 }
142}
143
144impl ToPrimitive for flex32 {
145 fn to_i64(&self) -> Option<i64> {
146 Some((*self).to_f32() as i64)
147 }
148
149 fn to_u64(&self) -> Option<u64> {
150 Some((*self).to_f32() as u64)
151 }
152
153 fn to_f32(&self) -> Option<f32> {
154 Some((*self).to_f32())
155 }
156
157 fn to_f64(&self) -> Option<f64> {
158 Some((*self).to_f32() as f64)
159 }
160}
161
162impl NumCast for flex32 {
163 fn from<T: num_traits::ToPrimitive>(n: T) -> Option<Self> {
164 Some(flex32::from_f32(n.to_f32()?))
165 }
166}
167
168impl num_traits::Float for flex32 {
169 fn nan() -> Self {
170 flex32(f32::nan())
171 }
172
173 fn infinity() -> Self {
174 flex32(f32::infinity())
175 }
176
177 fn neg_infinity() -> Self {
178 flex32(f32::neg_infinity())
179 }
180
181 fn neg_zero() -> Self {
182 flex32(f32::neg_zero())
183 }
184
185 fn min_value() -> Self {
186 flex32(<f32 as num_traits::Float>::min_value())
187 }
188
189 fn min_positive_value() -> Self {
190 flex32(f32::min_positive_value())
191 }
192
193 fn max_value() -> Self {
194 flex32(<f32 as num_traits::Float>::max_value())
195 }
196
197 fn is_nan(self) -> bool {
198 self.0.is_nan()
199 }
200
201 fn is_infinite(self) -> bool {
202 self.0.is_infinite()
203 }
204
205 fn is_finite(self) -> bool {
206 self.0.is_finite()
207 }
208
209 fn is_normal(self) -> bool {
210 self.0.is_normal()
211 }
212
213 fn classify(self) -> core::num::FpCategory {
214 self.0.classify()
215 }
216
217 fn floor(self) -> Self {
218 flex32(self.0.floor())
219 }
220
221 fn ceil(self) -> Self {
222 flex32(self.0.ceil())
223 }
224
225 fn round(self) -> Self {
226 flex32(self.0.round())
227 }
228
229 fn trunc(self) -> Self {
230 flex32(self.0.trunc())
231 }
232
233 fn fract(self) -> Self {
234 flex32(self.0.fract())
235 }
236
237 fn abs(self) -> Self {
238 flex32(self.0.abs())
239 }
240
241 fn signum(self) -> Self {
242 flex32(self.0.signum())
243 }
244
245 fn is_sign_positive(self) -> bool {
246 self.0.is_sign_positive()
247 }
248
249 fn is_sign_negative(self) -> bool {
250 self.0.is_sign_negative()
251 }
252
253 fn mul_add(self, a: Self, b: Self) -> Self {
254 flex32(self.0.mul_add(a.0, b.0))
255 }
256
257 fn recip(self) -> Self {
258 flex32(self.0.recip())
259 }
260
261 fn powi(self, n: i32) -> Self {
262 flex32(self.0.powi(n))
263 }
264
265 fn powf(self, n: Self) -> Self {
266 flex32(self.0.powf(n.0))
267 }
268
269 fn sqrt(self) -> Self {
270 flex32(self.0.sqrt())
271 }
272
273 fn exp(self) -> Self {
274 flex32(self.0.exp())
275 }
276
277 fn exp2(self) -> Self {
278 flex32(self.0.exp2())
279 }
280
281 fn ln(self) -> Self {
282 flex32(self.0.ln())
283 }
284
285 fn log(self, base: Self) -> Self {
286 flex32(self.0.log(base.0))
287 }
288
289 fn log2(self) -> Self {
290 flex32(self.0.log2())
291 }
292
293 fn log10(self) -> Self {
294 flex32(self.0.log10())
295 }
296
297 fn max(self, other: Self) -> Self {
298 flex32(self.0.max(other.0))
299 }
300
301 fn min(self, other: Self) -> Self {
302 flex32(self.0.min(other.0))
303 }
304
305 fn abs_sub(self, other: Self) -> Self {
306 flex32((self.0 - other.0).abs())
307 }
308
309 fn cbrt(self) -> Self {
310 flex32(self.0.cbrt())
311 }
312
313 fn hypot(self, other: Self) -> Self {
314 flex32(self.0.hypot(other.0))
315 }
316
317 fn sin(self) -> Self {
318 flex32(self.0.sin())
319 }
320
321 fn cos(self) -> Self {
322 flex32(self.0.cos())
323 }
324
325 fn tan(self) -> Self {
326 flex32(self.0.tan())
327 }
328
329 fn asin(self) -> Self {
330 flex32(self.0.asin())
331 }
332
333 fn acos(self) -> Self {
334 flex32(self.0.acos())
335 }
336
337 fn atan(self) -> Self {
338 flex32(self.0.atan())
339 }
340
341 fn atan2(self, other: Self) -> Self {
342 flex32(self.0.atan2(other.0))
343 }
344
345 fn sin_cos(self) -> (Self, Self) {
346 let (a, b) = self.0.sin_cos();
347 (flex32(a), flex32(b))
348 }
349
350 fn exp_m1(self) -> Self {
351 flex32(self.0.exp_m1())
352 }
353
354 fn ln_1p(self) -> Self {
355 flex32(self.0.ln_1p())
356 }
357
358 fn sinh(self) -> Self {
359 flex32(self.0.sinh())
360 }
361
362 fn cosh(self) -> Self {
363 flex32(self.0.cosh())
364 }
365
366 fn tanh(self) -> Self {
367 flex32(self.0.tanh())
368 }
369
370 fn asinh(self) -> Self {
371 flex32(self.0.asinh())
372 }
373
374 fn acosh(self) -> Self {
375 flex32(self.0.acosh())
376 }
377
378 fn atanh(self) -> Self {
379 flex32(self.0.atanh())
380 }
381
382 fn integer_decode(self) -> (u64, i16, i8) {
383 self.0.integer_decode()
384 }
385}
386
387impl One for flex32 {
388 fn one() -> Self {
389 flex32(1.0)
390 }
391}
392
393impl Zero for flex32 {
394 fn zero() -> Self {
395 flex32(0.0)
396 }
397
398 fn is_zero(&self) -> bool {
399 self.0 == 0.0
400 }
401}
402
403impl Num for flex32 {
404 type FromStrRadixErr = <f32 as Num>::FromStrRadixErr;
405
406 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
407 Ok(flex32(f32::from_str_radix(str, radix)?))
408 }
409}