radiate_utils/primitives/
float.rs1use crate::primitives::Primitive;
2use num_order::{NumHash, NumOrd};
3
4pub trait Float: Primitive + num_traits::Float + NumHash + NumOrd<Self> {
5 const THREE: Self;
6 const FOUR: Self;
7 const FIVE: Self;
8 const SIX: Self;
9 const EPS: Self;
10 const NAN: Self;
11
12 fn safe_clamp(self, min: Self, max: Self) -> Self {
13 if self.is_finite() {
14 self.clamp(min, max)
15 } else {
16 Self::EPS
17 }
18 }
19}
20
21#[macro_export]
22macro_rules! impl_float_scalar {
23 ($t:ty, $eps:expr) => {
24 impl Primitive for $t {
25 const HALF: Self = 0.5;
26 const MIN: Self = <$t>::MIN;
27 const MAX: Self = <$t>::MAX;
28 const ZERO: Self = 0.0;
29 const ONE: Self = 1.0;
30 const TWO: Self = 2.0;
31
32 #[inline]
33 fn safe_add(self, rhs: Self) -> Self {
34 self + rhs
35 }
36
37 #[inline]
38 fn safe_sub(self, rhs: Self) -> Self {
39 self - rhs
40 }
41
42 #[inline]
43 fn safe_mul(self, rhs: Self) -> Self {
44 (self * rhs)
45 }
46
47 #[inline]
48 fn safe_div(self, rhs: Self) -> Self {
49 if rhs == Self::ZERO { self } else { self / rhs }
50 }
51
52 #[inline]
53 fn safe_mean(self, rhs: Self) -> Self {
54 (self + rhs) * Self::HALF
55 }
56
57 #[inline]
58 fn is_equal(self, rhs: Self) -> bool {
59 (self - rhs).abs() <= $eps
60 }
61 }
62
63 impl Float for $t {
64 const THREE: Self = 3.0;
65 const FOUR: Self = 4.0;
66 const FIVE: Self = 5.0;
67 const SIX: Self = 6.0;
68 const NAN: Self = <$t>::NAN;
69 const EPS: Self = $eps;
70 }
71 };
72}
73
74impl_float_scalar!(f32, 1e-6_f32);
75impl_float_scalar!(f64, 1e-12_f64);