rosu_pp/util/
float_ext.rs

1pub trait FloatExt: Sized {
2    const EPS: Self;
3
4    /// `self == other`
5    fn eq(self, other: Self) -> bool {
6        self.almost_eq(other, Self::EPS)
7    }
8
9    /// `self ~= other` (within `acceptable_difference`)
10    fn almost_eq(self, other: Self, acceptable_difference: Self) -> bool;
11
12    /// `self != other`
13    fn not_eq(self, other: Self) -> bool;
14
15    /// Performs a linear interpolation between two values based on the given weight.
16    fn lerp(value1: Self, value2: Self, amount: Self) -> Self;
17}
18
19macro_rules! impl_float_ext {
20    ( $ty:ty ) => {
21        impl FloatExt for $ty {
22            const EPS: Self = <$ty>::EPSILON;
23
24            fn almost_eq(self, other: Self, acceptable_difference: Self) -> bool {
25                (self - other).abs() <= acceptable_difference
26            }
27
28            fn not_eq(self, other: Self) -> bool {
29                (self - other).abs() >= Self::EPS
30            }
31
32            // <https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/Double.cs#L841>
33            fn lerp(value1: Self, value2: Self, amount: Self) -> Self {
34                (value1 * (1.0 - amount)) + (value2 * amount)
35            }
36        }
37    };
38}
39
40impl_float_ext!(f32);
41impl_float_ext!(f64);