Skip to main content

a/math/complex/
float.rs

1//! The float types of the parts.
2
3use core::fmt;
4use core::iter::{Product, Sum};
5use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
6
7mod sealed {
8    pub trait Sealed {}
9    impl Sealed for f32 {}
10    impl Sealed for f64 {}
11}
12
13/// `f32` or `f64`: the type of the parts of a [`Complex`](super::Complex), and of the real numbers
14/// a matrix of either gives, such as its norms and singular values. The methods are those of the
15/// two types, for code generic over both. The trait is sealed.
16pub trait Float:
17    Copy
18    + Default
19    + PartialEq
20    + PartialOrd
21    + fmt::Debug
22    + fmt::Display
23    + fmt::LowerExp
24    + Add<Output = Self>
25    + Sub<Output = Self>
26    + Mul<Output = Self>
27    + Div<Output = Self>
28    + Rem<Output = Self>
29    + Neg<Output = Self>
30    + AddAssign
31    + SubAssign
32    + MulAssign
33    + DivAssign
34    + Sum
35    + Product
36    + Send
37    + Sync
38    + 'static
39    + sealed::Sealed
40{
41    /// 0.
42    const ZERO: Self;
43    /// 1.
44    const ONE: Self;
45    /// 2.
46    const TWO: Self;
47    /// 1/2.
48    const HALF: Self;
49    /// π.
50    const PI: Self;
51    /// Infinity.
52    const INFINITY: Self;
53    /// Not a number.
54    const NAN: Self;
55    /// The difference between 1 and the next larger float.
56    const EPSILON: Self;
57    /// The smallest positive normal float.
58    const MIN_POSITIVE: Self;
59    /// The largest finite float.
60    const MAX: Self;
61    /// The number of significant bits, the hidden one included.
62    const MANTISSA_DIGITS: u32;
63
64    /// The nearest float to `x`.
65    fn from_f64(x: f64) -> Self;
66    /// The value as an `f64`, exactly.
67    fn to_f64(self) -> f64;
68    /// The absolute value.
69    fn abs(self) -> Self;
70    /// The square root.
71    fn sqrt(self) -> Self;
72    /// `√(self² + other²)` without an overflow or underflow in the squares.
73    fn hypot(self, other: Self) -> Self;
74    /// The angle of the point `(other, self)`, in `[-π, π]`.
75    fn atan2(self, other: Self) -> Self;
76    /// The sine and the cosine.
77    fn sin_cos(self) -> (Self, Self);
78    /// `e^self`.
79    fn exp(self) -> Self;
80    /// The natural logarithm.
81    fn ln(self) -> Self;
82    /// `ln(1 + self)`, accurate near zero.
83    fn ln_1p(self) -> Self;
84    /// `self` to the integer power `n`.
85    fn powi(self, n: i32) -> Self;
86    /// `self · a + b` with one rounding.
87    fn mul_add(self, a: Self, b: Self) -> Self;
88    /// The absolute value of `self` with the sign of `sign`.
89    fn copysign(self, sign: Self) -> Self;
90    /// The larger of the two, ignoring a NaN.
91    fn max(self, other: Self) -> Self;
92    /// The smaller of the two, ignoring a NaN.
93    fn min(self, other: Self) -> Self;
94    /// Whether it is neither infinite nor NaN.
95    fn is_finite(self) -> bool;
96    /// Whether it is infinite.
97    fn is_infinite(self) -> bool;
98    /// Whether it is NaN.
99    fn is_nan(self) -> bool;
100    /// Whether its sign bit is set, as for `-0.0`.
101    fn is_sign_negative(self) -> bool;
102}
103
104macro_rules! float {
105    ($t:ident) => {
106        impl Float for $t {
107            const ZERO: Self = 0.0;
108            const ONE: Self = 1.0;
109            const TWO: Self = 2.0;
110            const HALF: Self = 0.5;
111            const PI: Self = core::$t::consts::PI;
112            const INFINITY: Self = $t::INFINITY;
113            const NAN: Self = $t::NAN;
114            const EPSILON: Self = $t::EPSILON;
115            const MIN_POSITIVE: Self = $t::MIN_POSITIVE;
116            const MAX: Self = $t::MAX;
117            const MANTISSA_DIGITS: u32 = $t::MANTISSA_DIGITS;
118
119            #[inline]
120            fn from_f64(x: f64) -> Self {
121                x as $t
122            }
123            #[inline]
124            fn to_f64(self) -> f64 {
125                self as f64
126            }
127            #[inline]
128            fn abs(self) -> Self {
129                $t::abs(self)
130            }
131            #[inline]
132            fn sqrt(self) -> Self {
133                $t::sqrt(self)
134            }
135            #[inline]
136            fn hypot(self, other: Self) -> Self {
137                $t::hypot(self, other)
138            }
139            #[inline]
140            fn atan2(self, other: Self) -> Self {
141                $t::atan2(self, other)
142            }
143            #[inline]
144            fn sin_cos(self) -> (Self, Self) {
145                $t::sin_cos(self)
146            }
147            #[inline]
148            fn exp(self) -> Self {
149                $t::exp(self)
150            }
151            #[inline]
152            fn ln(self) -> Self {
153                $t::ln(self)
154            }
155            #[inline]
156            fn ln_1p(self) -> Self {
157                $t::ln_1p(self)
158            }
159            #[inline]
160            fn powi(self, n: i32) -> Self {
161                $t::powi(self, n)
162            }
163            #[inline]
164            fn mul_add(self, a: Self, b: Self) -> Self {
165                $t::mul_add(self, a, b)
166            }
167            #[inline]
168            fn copysign(self, sign: Self) -> Self {
169                $t::copysign(self, sign)
170            }
171            #[inline]
172            fn max(self, other: Self) -> Self {
173                $t::max(self, other)
174            }
175            #[inline]
176            fn min(self, other: Self) -> Self {
177                $t::min(self, other)
178            }
179            #[inline]
180            fn is_finite(self) -> bool {
181                $t::is_finite(self)
182            }
183            #[inline]
184            fn is_infinite(self) -> bool {
185                $t::is_infinite(self)
186            }
187            #[inline]
188            fn is_nan(self) -> bool {
189                $t::is_nan(self)
190            }
191            #[inline]
192            fn is_sign_negative(self) -> bool {
193                $t::is_sign_negative(self)
194            }
195        }
196    };
197}
198
199float!(f32);
200float!(f64);