typed_floats/types/f32/
non_nan.rs

1use crate::types::{f32, InvalidNumber, NonNaN};
2use const_fn::const_fn;
3
4impl NonNaN<f32> {
5    /// Creates a new value from a primitive type
6    /// It adds a little overhead compared to `new_unchecked`
7    /// because it checks that the value is valid
8    ///
9    /// # Examples
10    ///
11    /// ```
12    /// # use typed_floats::tf32::NonNaN;
13    /// let x = NonNaN::new(3.0).unwrap();
14    ///
15    /// assert_eq!(x, 3.0);
16    /// ```
17    ///
18    /// # Errors
19    /// Returns an error if the value is not valid
20    #[inline]
21    #[const_fn("1.83")]
22    pub const fn new(value: f32) -> Result<Self, InvalidNumber> {
23        if value.is_nan() {
24            return Err(InvalidNumber::NaN);
25        }
26
27        Ok(Self(value))
28    }
29
30    /// Creates a new value from a primitive type with zero overhead (in release mode).
31    /// It is up to the caller to ensure that the value is valid
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// # use typed_floats::tf32::NonNaN;
37    /// let x = unsafe { NonNaN::new_unchecked(3.0) };
38    ///
39    /// assert_eq!(x, 3.0);
40    /// ```
41    /// # Safety
42    /// The caller must ensure that the value is valid.
43    /// It will panic in debug mode if the value is not valid,
44    /// but in release mode the behavior is undefined
45    #[inline]
46    #[must_use]
47    #[const_fn("1.83")]
48    pub const unsafe fn new_unchecked(value: f32) -> Self {
49        crate::macros::new_unchecked!(value, NonNaN)
50    }
51
52    /// Returns the value as a primitive type
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use typed_floats::tf32::NonNaN;
58    ///
59    /// let x = NonNaN::new(3.0).unwrap();
60    ///
61    /// let y: f32 = x.into();
62    ///
63    /// assert_eq!(y, 3.0);
64    /// ```
65    #[inline]
66    #[must_use]
67    pub const fn get(&self) -> f32 {
68        self.0
69    }
70
71    /// Returns `true` if this value is NaN.
72    /// This is never the case for the provided types
73    ///
74    /// # Examples
75    ///
76    /// ```
77    /// use typed_floats::tf32::NonNaN;
78    /// let x: NonNaN = 3.0.try_into().unwrap();
79    ///
80    /// assert_eq!(x.is_nan(), false);
81    /// ```
82    ///
83    /// See [`f32::is_nan()`] for more details.
84    #[inline]
85    #[must_use]
86    #[const_fn("1.83")]
87    pub const fn is_nan(&self) -> bool {
88        false
89    }
90
91    /// Returns `true` if this value is positive infinity or negative infinity.
92    ///
93    /// # Examples
94    ///
95    /// ```
96    /// use typed_floats::tf32::NonNaN;
97    /// let x: NonNaN = 3.0.try_into().unwrap();
98    ///
99    /// assert_eq!(x.is_infinite(), false);
100    /// ```
101    ///
102    /// See [`f32::is_infinite()`] for more details.
103    #[inline]
104    #[must_use]
105    #[const_fn("1.83")]
106    pub const fn is_infinite(&self) -> bool {
107        self.0.is_infinite()
108    }
109
110    /// Returns `true` if this number is positive infinity nor negative infinity.
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// use typed_floats::tf32::NonNaN;
116    /// let x: NonNaN = 3.0.try_into().unwrap();
117    ///
118    /// assert_eq!(x.is_finite(), true);
119    /// ```
120    ///
121    /// See [`f32::is_finite()`] for more details.
122    #[inline]
123    #[must_use]
124    #[const_fn("1.83")]
125    pub const fn is_finite(&self) -> bool {
126        self.0.is_finite()
127    }
128
129    /// Returns `true` if the number is [subnormal](https://en.wikipedia.org/wiki/Denormal_number).
130    ///
131    /// # Examples
132    ///
133    /// ```
134    /// use typed_floats::tf32::NonNaN;
135    /// let x: NonNaN = 3.0.try_into().unwrap();
136    ///
137    /// assert_eq!(x.is_subnormal(), false);
138    /// ```
139    ///
140    /// See [`f32::is_subnormal()`] for more details.
141    #[inline]
142    #[must_use]
143    #[const_fn("1.83")]
144    pub const fn is_subnormal(&self) -> bool {
145        self.0.is_subnormal()
146    }
147
148    /// Returns `true` if the number is neither zero, infinite or [subnormal](https://en.wikipedia.org/wiki/Denormal_number).
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use typed_floats::tf32::NonNaN;
154    /// let x: NonNaN = 3.0.try_into().unwrap();
155    ///
156    /// assert_eq!(x.is_normal(), true);
157    /// ```
158    ///
159    /// See [`f32::is_normal()`] for more details.
160    #[inline]
161    #[must_use]
162    #[const_fn("1.83")]
163    pub const fn is_normal(&self) -> bool {
164        self.0.is_normal()
165    }
166
167    /// Returns the floating point category of the number. If only one property
168    /// is going to be tested, it is generally faster to use the specific
169    /// predicate instead.
170    ///
171    /// # Examples
172    ///
173    /// ```
174    /// use typed_floats::tf32::NonNaN;
175    /// let x: NonNaN = 3.0.try_into().unwrap();
176    ///
177    /// assert_eq!(x.classify(), core::num::FpCategory::Normal);
178    /// ```
179    ///
180    /// See [`f32::classify()`] for more details.
181    #[inline]
182    #[must_use]
183    #[const_fn("1.83")]
184    pub const fn classify(&self) -> core::num::FpCategory {
185        self.0.classify()
186    }
187
188    /// Returns `true` if `self` has a positive sign, including `+0.0` and positive infinity.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// use typed_floats::tf32::NonNaN;
194    /// let x: NonNaN = 3.0.try_into().unwrap();
195    ///
196    /// assert_eq!(x.is_sign_positive(), true);
197    /// ```
198    ///
199    /// See [`f32::is_sign_positive()`] for more details.
200    #[inline]
201    #[must_use]
202    #[const_fn("1.83")]
203    pub const fn is_sign_positive(&self) -> bool {
204        self.0.is_sign_positive()
205    }
206
207    /// Returns `true` if `self` has a negative sign, including `-0.0` and negative infinity.
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// use typed_floats::tf32::NonNaN;
213    /// let x: NonNaN = 3.0.try_into().unwrap();
214    ///
215    /// assert_eq!(x.is_sign_negative(), false);
216    /// ```
217    ///
218    /// See [`f32::is_sign_negative()`] for more details.
219    #[inline]
220    #[must_use]
221    #[const_fn("1.83")]
222    pub const fn is_sign_negative(&self) -> bool {
223        self.0.is_sign_negative()
224    }
225
226    /// Returns `true` if the number is negative zero.
227    ///     
228    /// # Examples
229    ///
230    /// ```
231    /// use typed_floats::tf32::NonNaN;
232    /// let x: NonNaN = 3.0.try_into().unwrap();
233    /// let y: NonNaN = (-0.0).try_into().unwrap();
234    /// let z: NonNaN = 0.0.try_into().unwrap();
235    ///
236    /// assert_eq!(x.is_negative_zero(), false);
237    /// assert_eq!(y.is_negative_zero(), true);
238    /// assert_eq!(z.is_negative_zero(), false);
239    /// ```
240    #[inline]
241    #[must_use]
242    #[const_fn("1.83")]
243    pub const fn is_negative_zero(&self) -> bool {
244        self.0 == 0.0 && self.0.is_sign_negative()
245    }
246
247    /// Returns `true` if the number is positive zero.
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// use typed_floats::tf32::NonNaN;
253    /// let x: NonNaN = 3.0.try_into().unwrap();
254    /// let y: NonNaN = (-0.0).try_into().unwrap();
255    /// let z: NonNaN = 0.0.try_into().unwrap();
256    ///
257    /// assert_eq!(x.is_positive_zero(), false);
258    /// assert_eq!(y.is_positive_zero(), false);
259    /// assert_eq!(z.is_positive_zero(), true);
260    /// ```
261    #[inline]
262    #[must_use]
263    #[const_fn("1.83")]
264    pub const fn is_positive_zero(&self) -> bool {
265        self.0 == 0.0 && self.0.is_sign_positive()
266    }
267}