typed_floats/types/f64/
non_nan_finite.rs

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