Skip to main content

core/num/
f16.rs

1//! Constants for the `f16` half-precision floating point type.
2//!
3//! *[See also the `f16` primitive type][f16].*
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
6//!
7//! For the constants defined directly in this module
8//! (as distinct from those defined in the `consts` sub-module),
9//! new code should instead use the associated constants
10//! defined directly on the `f16` type.
11
12#![unstable(feature = "f16", issue = "116909")]
13
14use crate::convert::FloatToInt;
15use crate::num::FpCategory;
16#[cfg(not(test))]
17use crate::num::imp::libm;
18use crate::panic::const_assert;
19use crate::{intrinsics, mem};
20
21/// Basic mathematical constants.
22#[unstable(feature = "f16", issue = "116909")]
23#[rustc_diagnostic_item = "f16_consts_mod"]
24pub mod consts {
25    // FIXME: replace with mathematical constants from cmath.
26
27    /// Archimedes' constant (π)
28    #[unstable(feature = "f16", issue = "116909")]
29    pub const PI: f16 = 3.14159265358979323846264338327950288_f16;
30
31    /// The full circle constant (τ)
32    ///
33    /// Equal to 2π.
34    #[unstable(feature = "f16", issue = "116909")]
35    pub const TAU: f16 = 6.28318530717958647692528676655900577_f16;
36
37    /// The golden ratio (φ)
38    #[unstable(feature = "f16", issue = "116909")]
39    pub const GOLDEN_RATIO: f16 = 1.618033988749894848204586834365638118_f16;
40
41    /// The Euler-Mascheroni constant (γ)
42    #[unstable(feature = "f16", issue = "116909")]
43    pub const EULER_GAMMA: f16 = 0.577215664901532860606512090082402431_f16;
44
45    /// π/2
46    #[unstable(feature = "f16", issue = "116909")]
47    pub const FRAC_PI_2: f16 = 1.57079632679489661923132169163975144_f16;
48
49    /// π/3
50    #[unstable(feature = "f16", issue = "116909")]
51    pub const FRAC_PI_3: f16 = 1.04719755119659774615421446109316763_f16;
52
53    /// π/4
54    #[unstable(feature = "f16", issue = "116909")]
55    pub const FRAC_PI_4: f16 = 0.785398163397448309615660845819875721_f16;
56
57    /// π/6
58    #[unstable(feature = "f16", issue = "116909")]
59    pub const FRAC_PI_6: f16 = 0.52359877559829887307710723054658381_f16;
60
61    /// π/8
62    #[unstable(feature = "f16", issue = "116909")]
63    pub const FRAC_PI_8: f16 = 0.39269908169872415480783042290993786_f16;
64
65    /// 1/π
66    #[unstable(feature = "f16", issue = "116909")]
67    pub const FRAC_1_PI: f16 = 0.318309886183790671537767526745028724_f16;
68
69    /// 1/sqrt(π)
70    #[unstable(feature = "f16", issue = "116909")]
71    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
72    pub const FRAC_1_SQRT_PI: f16 = 0.564189583547756286948079451560772586_f16;
73
74    /// 1/sqrt(2π)
75    #[doc(alias = "FRAC_1_SQRT_TAU")]
76    #[unstable(feature = "f16", issue = "116909")]
77    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
78    pub const FRAC_1_SQRT_2PI: f16 = 0.398942280401432677939946059934381868_f16;
79
80    /// 2/π
81    #[unstable(feature = "f16", issue = "116909")]
82    pub const FRAC_2_PI: f16 = 0.636619772367581343075535053490057448_f16;
83
84    /// 2/sqrt(π)
85    #[unstable(feature = "f16", issue = "116909")]
86    pub const FRAC_2_SQRT_PI: f16 = 1.12837916709551257389615890312154517_f16;
87
88    /// sqrt(2)
89    #[unstable(feature = "f16", issue = "116909")]
90    pub const SQRT_2: f16 = 1.41421356237309504880168872420969808_f16;
91
92    /// 1/sqrt(2)
93    #[unstable(feature = "f16", issue = "116909")]
94    pub const FRAC_1_SQRT_2: f16 = 0.707106781186547524400844362104849039_f16;
95
96    /// sqrt(3)
97    #[unstable(feature = "f16", issue = "116909")]
98    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
99    pub const SQRT_3: f16 = 1.732050807568877293527446341505872367_f16;
100
101    /// 1/sqrt(3)
102    #[unstable(feature = "f16", issue = "116909")]
103    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
104    pub const FRAC_1_SQRT_3: f16 = 0.577350269189625764509148780501957456_f16;
105
106    /// sqrt(5)
107    #[unstable(feature = "more_float_constants", issue = "146939")]
108    // Also, #[unstable(feature = "f16", issue = "116909")]
109    pub const SQRT_5: f16 = 2.23606797749978969640917366873127623_f16;
110
111    /// 1/sqrt(5)
112    #[unstable(feature = "more_float_constants", issue = "146939")]
113    // Also, #[unstable(feature = "f16", issue = "116909")]
114    pub const FRAC_1_SQRT_5: f16 = 0.44721359549995793928183473374625524_f16;
115
116    /// Euler's number (e)
117    #[unstable(feature = "f16", issue = "116909")]
118    pub const E: f16 = 2.71828182845904523536028747135266250_f16;
119
120    /// log<sub>2</sub>(10)
121    #[unstable(feature = "f16", issue = "116909")]
122    pub const LOG2_10: f16 = 3.32192809488736234787031942948939018_f16;
123
124    /// log<sub>2</sub>(e)
125    #[unstable(feature = "f16", issue = "116909")]
126    pub const LOG2_E: f16 = 1.44269504088896340735992468100189214_f16;
127
128    /// log<sub>10</sub>(2)
129    #[unstable(feature = "f16", issue = "116909")]
130    pub const LOG10_2: f16 = 0.301029995663981195213738894724493027_f16;
131
132    /// log<sub>10</sub>(e)
133    #[unstable(feature = "f16", issue = "116909")]
134    pub const LOG10_E: f16 = 0.434294481903251827651128918916605082_f16;
135
136    /// ln(2)
137    #[unstable(feature = "f16", issue = "116909")]
138    pub const LN_2: f16 = 0.693147180559945309417232121458176568_f16;
139
140    /// ln(10)
141    #[unstable(feature = "f16", issue = "116909")]
142    pub const LN_10: f16 = 2.30258509299404568401799145468436421_f16;
143}
144
145#[doc(test(attr(
146    feature(cfg_target_has_reliable_f16_f128),
147    allow(internal_features, unused_features)
148)))]
149impl f16 {
150    /// The radix or base of the internal representation of `f16`.
151    #[unstable(feature = "f16", issue = "116909")]
152    pub const RADIX: u32 = 2;
153
154    /// The size of this float type in bits.
155    // #[unstable(feature = "f16", issue = "116909")]
156    #[unstable(feature = "float_bits_const", issue = "151073")]
157    pub const BITS: u32 = 16;
158
159    /// Number of significant digits in base 2.
160    ///
161    /// Note that the size of the mantissa in the bitwise representation is one
162    /// smaller than this since the leading 1 is not stored explicitly.
163    #[unstable(feature = "f16", issue = "116909")]
164    pub const MANTISSA_DIGITS: u32 = 11;
165
166    /// Approximate number of significant digits in base 10.
167    ///
168    /// This is the maximum <i>x</i> such that any decimal number with <i>x</i>
169    /// significant digits can be converted to `f16` and back without loss.
170    ///
171    /// Equal to floor(log<sub>10</sub>&nbsp;2<sup>[`MANTISSA_DIGITS`]&nbsp;&minus;&nbsp;1</sup>).
172    ///
173    /// [`MANTISSA_DIGITS`]: f16::MANTISSA_DIGITS
174    #[unstable(feature = "f16", issue = "116909")]
175    pub const DIGITS: u32 = 3;
176
177    /// [Machine epsilon] value for `f16`.
178    ///
179    /// This is the difference between `1.0` and the next larger representable number.
180    ///
181    /// Equal to 2<sup>1&nbsp;&minus;&nbsp;[`MANTISSA_DIGITS`]</sup>.
182    ///
183    /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
184    /// [`MANTISSA_DIGITS`]: f16::MANTISSA_DIGITS
185    #[unstable(feature = "f16", issue = "116909")]
186    #[rustc_diagnostic_item = "f16_epsilon"]
187    pub const EPSILON: f16 = 9.7656e-4_f16;
188
189    /// Smallest finite `f16` value.
190    ///
191    /// Equal to &minus;[`MAX`].
192    ///
193    /// [`MAX`]: f16::MAX
194    #[unstable(feature = "f16", issue = "116909")]
195    pub const MIN: f16 = -6.5504e+4_f16;
196    /// Smallest positive normal `f16` value.
197    ///
198    /// Equal to 2<sup>[`MIN_EXP`]&nbsp;&minus;&nbsp;1</sup>.
199    ///
200    /// [`MIN_EXP`]: f16::MIN_EXP
201    #[unstable(feature = "f16", issue = "116909")]
202    pub const MIN_POSITIVE: f16 = 6.1035e-5_f16;
203    /// Largest finite `f16` value.
204    ///
205    /// Equal to
206    /// (1&nbsp;&minus;&nbsp;2<sup>&minus;[`MANTISSA_DIGITS`]</sup>)&nbsp;2<sup>[`MAX_EXP`]</sup>.
207    ///
208    /// [`MANTISSA_DIGITS`]: f16::MANTISSA_DIGITS
209    /// [`MAX_EXP`]: f16::MAX_EXP
210    #[unstable(feature = "f16", issue = "116909")]
211    pub const MAX: f16 = 6.5504e+4_f16;
212
213    /// One greater than the minimum possible *normal* power of 2 exponent
214    /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition).
215    ///
216    /// This corresponds to the exact minimum possible *normal* power of 2 exponent
217    /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition).
218    /// In other words, all normal numbers representable by this type are
219    /// greater than or equal to 0.5&nbsp;×&nbsp;2<sup><i>MIN_EXP</i></sup>.
220    #[unstable(feature = "f16", issue = "116909")]
221    pub const MIN_EXP: i32 = -13;
222    /// One greater than the maximum possible power of 2 exponent
223    /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition).
224    ///
225    /// This corresponds to the exact maximum possible power of 2 exponent
226    /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition).
227    /// In other words, all numbers representable by this type are
228    /// strictly less than 2<sup><i>MAX_EXP</i></sup>.
229    #[unstable(feature = "f16", issue = "116909")]
230    pub const MAX_EXP: i32 = 16;
231
232    /// Minimum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
233    ///
234    /// Equal to ceil(log<sub>10</sub>&nbsp;[`MIN_POSITIVE`]).
235    ///
236    /// [`MIN_POSITIVE`]: f16::MIN_POSITIVE
237    #[unstable(feature = "f16", issue = "116909")]
238    pub const MIN_10_EXP: i32 = -4;
239    /// Maximum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
240    ///
241    /// Equal to floor(log<sub>10</sub>&nbsp;[`MAX`]).
242    ///
243    /// [`MAX`]: f16::MAX
244    #[unstable(feature = "f16", issue = "116909")]
245    pub const MAX_10_EXP: i32 = 4;
246
247    /// Not a Number (NaN).
248    ///
249    /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
250    /// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
251    /// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
252    /// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
253    /// info.
254    ///
255    /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
256    /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
257    /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
258    /// The concrete bit pattern may change across Rust versions and target platforms.
259    #[allow(clippy::eq_op)]
260    #[rustc_diagnostic_item = "f16_nan"]
261    #[unstable(feature = "f16", issue = "116909")]
262    pub const NAN: f16 = 0.0_f16 / 0.0_f16;
263
264    /// Infinity (∞).
265    #[unstable(feature = "f16", issue = "116909")]
266    pub const INFINITY: f16 = 1.0_f16 / 0.0_f16;
267
268    /// Negative infinity (−∞).
269    #[unstable(feature = "f16", issue = "116909")]
270    pub const NEG_INFINITY: f16 = -1.0_f16 / 0.0_f16;
271
272    /// Maximum integer that can be represented exactly in an [`f16`] value,
273    /// with no other integer converting to the same floating point value.
274    ///
275    /// For an integer `x` which satisfies `MIN_EXACT_INTEGER <= x <= MAX_EXACT_INTEGER`,
276    /// there is a "one-to-one" mapping between [`i16`] and [`f16`] values.
277    /// `MAX_EXACT_INTEGER + 1` also converts losslessly to [`f16`] and back to
278    /// [`i16`], but `MAX_EXACT_INTEGER + 2` converts to the same [`f16`] value
279    /// (and back to `MAX_EXACT_INTEGER + 1` as an integer) so there is not a
280    /// "one-to-one" mapping.
281    ///
282    /// [`MAX_EXACT_INTEGER`]: f16::MAX_EXACT_INTEGER
283    /// [`MIN_EXACT_INTEGER`]: f16::MIN_EXACT_INTEGER
284    /// ```
285    /// #![feature(f16)]
286    /// #![feature(float_exact_integer_constants)]
287    /// # // FIXME(#152635): Float rounding on `i586` does not adhere to IEEE 754
288    /// # #[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))] {
289    /// # #[cfg(target_has_reliable_f16)] {
290    /// let max_exact_int = f16::MAX_EXACT_INTEGER;
291    /// assert_eq!(max_exact_int, max_exact_int as f16 as i16);
292    /// assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f16 as i16);
293    /// assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f16 as i16);
294    ///
295    /// // Beyond `f16::MAX_EXACT_INTEGER`, multiple integers can map to one float value
296    /// assert_eq!((max_exact_int + 1) as f16, (max_exact_int + 2) as f16);
297    /// # }}
298    /// ```
299    // #[unstable(feature = "f16", issue = "116909")]
300    #[unstable(feature = "float_exact_integer_constants", issue = "152466")]
301    pub const MAX_EXACT_INTEGER: i16 = (1 << Self::MANTISSA_DIGITS) - 1;
302
303    /// Minimum integer that can be represented exactly in an [`f16`] value,
304    /// with no other integer converting to the same floating point value.
305    ///
306    /// For an integer `x` which satisfies `MIN_EXACT_INTEGER <= x <= MAX_EXACT_INTEGER`,
307    /// there is a "one-to-one" mapping between [`i16`] and [`f16`] values.
308    /// `MAX_EXACT_INTEGER + 1` also converts losslessly to [`f16`] and back to
309    /// [`i16`], but `MAX_EXACT_INTEGER + 2` converts to the same [`f16`] value
310    /// (and back to `MAX_EXACT_INTEGER + 1` as an integer) so there is not a
311    /// "one-to-one" mapping.
312    ///
313    /// This constant is equivalent to `-MAX_EXACT_INTEGER`.
314    ///
315    /// [`MAX_EXACT_INTEGER`]: f16::MAX_EXACT_INTEGER
316    /// [`MIN_EXACT_INTEGER`]: f16::MIN_EXACT_INTEGER
317    /// ```
318    /// #![feature(f16)]
319    /// #![feature(float_exact_integer_constants)]
320    /// # // FIXME(#152635): Float rounding on `i586` does not adhere to IEEE 754
321    /// # #[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))] {
322    /// # #[cfg(target_has_reliable_f16)] {
323    /// let min_exact_int = f16::MIN_EXACT_INTEGER;
324    /// assert_eq!(min_exact_int, min_exact_int as f16 as i16);
325    /// assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f16 as i16);
326    /// assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f16 as i16);
327    ///
328    /// // Below `f16::MIN_EXACT_INTEGER`, multiple integers can map to one float value
329    /// assert_eq!((min_exact_int - 1) as f16, (min_exact_int - 2) as f16);
330    /// # }}
331    /// ```
332    // #[unstable(feature = "f16", issue = "116909")]
333    #[unstable(feature = "float_exact_integer_constants", issue = "152466")]
334    pub const MIN_EXACT_INTEGER: i16 = -Self::MAX_EXACT_INTEGER;
335
336    /// Sign bit
337    pub(crate) const SIGN_MASK: u16 = 0x8000;
338
339    /// Exponent mask
340    pub(crate) const EXP_MASK: u16 = 0x7c00;
341
342    /// Mantissa mask
343    pub(crate) const MAN_MASK: u16 = 0x03ff;
344
345    /// Minimum representable positive value (min subnormal)
346    const TINY_BITS: u16 = 0x1;
347
348    /// Minimum representable negative value (min negative subnormal)
349    const NEG_TINY_BITS: u16 = Self::TINY_BITS | Self::SIGN_MASK;
350
351    /// Returns `true` if this value is NaN.
352    ///
353    /// ```
354    /// #![feature(f16)]
355    /// # #[cfg(target_has_reliable_f16)] {
356    ///
357    /// let nan = f16::NAN;
358    /// let f = 7.0_f16;
359    ///
360    /// assert!(nan.is_nan());
361    /// assert!(!f.is_nan());
362    /// # }
363    /// ```
364    #[inline]
365    #[must_use]
366    #[unstable(feature = "f16", issue = "116909")]
367    #[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :)
368    pub const fn is_nan(self) -> bool {
369        self != self
370    }
371
372    /// Returns `true` if this value is positive infinity or negative infinity, and
373    /// `false` otherwise.
374    ///
375    /// ```
376    /// #![feature(f16)]
377    /// # #[cfg(target_has_reliable_f16)] {
378    ///
379    /// let f = 7.0f16;
380    /// let inf = f16::INFINITY;
381    /// let neg_inf = f16::NEG_INFINITY;
382    /// let nan = f16::NAN;
383    ///
384    /// assert!(!f.is_infinite());
385    /// assert!(!nan.is_infinite());
386    ///
387    /// assert!(inf.is_infinite());
388    /// assert!(neg_inf.is_infinite());
389    /// # }
390    /// ```
391    #[inline]
392    #[must_use]
393    #[unstable(feature = "f16", issue = "116909")]
394    pub const fn is_infinite(self) -> bool {
395        (self == f16::INFINITY) | (self == f16::NEG_INFINITY)
396    }
397
398    /// Returns `true` if this number is neither infinite nor NaN.
399    ///
400    /// ```
401    /// #![feature(f16)]
402    /// # #[cfg(target_has_reliable_f16)] {
403    ///
404    /// let f = 7.0f16;
405    /// let inf: f16 = f16::INFINITY;
406    /// let neg_inf: f16 = f16::NEG_INFINITY;
407    /// let nan: f16 = f16::NAN;
408    ///
409    /// assert!(f.is_finite());
410    ///
411    /// assert!(!nan.is_finite());
412    /// assert!(!inf.is_finite());
413    /// assert!(!neg_inf.is_finite());
414    /// # }
415    /// ```
416    #[inline]
417    #[must_use]
418    #[unstable(feature = "f16", issue = "116909")]
419    #[rustc_const_unstable(feature = "f16", issue = "116909")]
420    pub const fn is_finite(self) -> bool {
421        // There's no need to handle NaN separately: if self is NaN,
422        // the comparison is not true, exactly as desired.
423        self.abs() < Self::INFINITY
424    }
425
426    /// Returns `true` if the number is [subnormal].
427    ///
428    /// ```
429    /// #![feature(f16)]
430    /// # #[cfg(target_has_reliable_f16)] {
431    ///
432    /// let min = f16::MIN_POSITIVE; // 6.1035e-5
433    /// let max = f16::MAX;
434    /// let lower_than_min = 1.0e-7_f16;
435    /// let zero = 0.0_f16;
436    ///
437    /// assert!(!min.is_subnormal());
438    /// assert!(!max.is_subnormal());
439    ///
440    /// assert!(!zero.is_subnormal());
441    /// assert!(!f16::NAN.is_subnormal());
442    /// assert!(!f16::INFINITY.is_subnormal());
443    /// // Values between `0` and `min` are Subnormal.
444    /// assert!(lower_than_min.is_subnormal());
445    /// # }
446    /// ```
447    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
448    #[inline]
449    #[must_use]
450    #[unstable(feature = "f16", issue = "116909")]
451    pub const fn is_subnormal(self) -> bool {
452        matches!(self.classify(), FpCategory::Subnormal)
453    }
454
455    /// Returns `true` if the number is neither zero, infinite, [subnormal], or NaN.
456    ///
457    /// ```
458    /// #![feature(f16)]
459    /// # #[cfg(target_has_reliable_f16)] {
460    ///
461    /// let min = f16::MIN_POSITIVE; // 6.1035e-5
462    /// let max = f16::MAX;
463    /// let lower_than_min = 1.0e-7_f16;
464    /// let zero = 0.0_f16;
465    ///
466    /// assert!(min.is_normal());
467    /// assert!(max.is_normal());
468    ///
469    /// assert!(!zero.is_normal());
470    /// assert!(!f16::NAN.is_normal());
471    /// assert!(!f16::INFINITY.is_normal());
472    /// // Values between `0` and `min` are Subnormal.
473    /// assert!(!lower_than_min.is_normal());
474    /// # }
475    /// ```
476    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
477    #[inline]
478    #[must_use]
479    #[unstable(feature = "f16", issue = "116909")]
480    pub const fn is_normal(self) -> bool {
481        matches!(self.classify(), FpCategory::Normal)
482    }
483
484    /// Returns the floating point category of the number. If only one property
485    /// is going to be tested, it is generally faster to use the specific
486    /// predicate instead.
487    ///
488    /// ```
489    /// #![feature(f16)]
490    /// # #[cfg(target_has_reliable_f16)] {
491    ///
492    /// use std::num::FpCategory;
493    ///
494    /// let num = 12.4_f16;
495    /// let inf = f16::INFINITY;
496    ///
497    /// assert_eq!(num.classify(), FpCategory::Normal);
498    /// assert_eq!(inf.classify(), FpCategory::Infinite);
499    /// # }
500    /// ```
501    #[ferrocene::prevalidated]
502    #[inline]
503    #[unstable(feature = "f16", issue = "116909")]
504    #[must_use]
505    pub const fn classify(self) -> FpCategory {
506        let b = self.to_bits();
507        match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
508            (0, Self::EXP_MASK) => FpCategory::Infinite,
509            (_, Self::EXP_MASK) => FpCategory::Nan,
510            (0, 0) => FpCategory::Zero,
511            (_, 0) => FpCategory::Subnormal,
512            _ => FpCategory::Normal,
513        }
514    }
515
516    /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
517    /// positive sign bit and positive infinity.
518    ///
519    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
520    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
521    /// conserved over arithmetic operations, the result of `is_sign_positive` on
522    /// a NaN might produce an unexpected or non-portable result. See the [specification
523    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0`
524    /// if you need fully portable behavior (will return `false` for all NaNs).
525    ///
526    /// ```
527    /// #![feature(f16)]
528    /// # #[cfg(target_has_reliable_f16)] {
529    ///
530    /// let f = 7.0_f16;
531    /// let g = -7.0_f16;
532    ///
533    /// assert!(f.is_sign_positive());
534    /// assert!(!g.is_sign_positive());
535    /// # }
536    /// ```
537    #[inline]
538    #[must_use]
539    #[unstable(feature = "f16", issue = "116909")]
540    pub const fn is_sign_positive(self) -> bool {
541        !self.is_sign_negative()
542    }
543
544    /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
545    /// negative sign bit and negative infinity.
546    ///
547    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
548    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
549    /// conserved over arithmetic operations, the result of `is_sign_negative` on
550    /// a NaN might produce an unexpected or non-portable result. See the [specification
551    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0`
552    /// if you need fully portable behavior (will return `false` for all NaNs).
553    ///
554    /// ```
555    /// #![feature(f16)]
556    /// # #[cfg(target_has_reliable_f16)] {
557    ///
558    /// let f = 7.0_f16;
559    /// let g = -7.0_f16;
560    ///
561    /// assert!(!f.is_sign_negative());
562    /// assert!(g.is_sign_negative());
563    /// # }
564    /// ```
565    #[inline]
566    #[must_use]
567    #[unstable(feature = "f16", issue = "116909")]
568    pub const fn is_sign_negative(self) -> bool {
569        // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
570        // applies to zeros and NaNs as well.
571        // SAFETY: This is just transmuting to get the sign bit, it's fine.
572        (self.to_bits() & (1 << 15)) != 0
573    }
574
575    /// Returns the least number greater than `self`.
576    ///
577    /// Let `TINY` be the smallest representable positive `f16`. Then,
578    ///  - if `self.is_nan()`, this returns `self`;
579    ///  - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
580    ///  - if `self` is `-TINY`, this returns -0.0;
581    ///  - if `self` is -0.0 or +0.0, this returns `TINY`;
582    ///  - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
583    ///  - otherwise the unique least value greater than `self` is returned.
584    ///
585    /// The identity `x.next_up() == -(-x).next_down()` holds for all non-NaN `x`. When `x`
586    /// is finite `x == x.next_up().next_down()` also holds.
587    ///
588    /// ```rust
589    /// #![feature(f16)]
590    /// # #[cfg(target_has_reliable_f16)] {
591    ///
592    /// // f16::EPSILON is the difference between 1.0 and the next number up.
593    /// assert_eq!(1.0f16.next_up(), 1.0 + f16::EPSILON);
594    /// // But not for most numbers.
595    /// assert!(0.1f16.next_up() < 0.1 + f16::EPSILON);
596    /// assert_eq!(4356f16.next_up(), 4360.0);
597    /// # }
598    /// ```
599    ///
600    /// This operation corresponds to IEEE-754 `nextUp`.
601    ///
602    /// [`NEG_INFINITY`]: Self::NEG_INFINITY
603    /// [`INFINITY`]: Self::INFINITY
604    /// [`MIN`]: Self::MIN
605    /// [`MAX`]: Self::MAX
606    #[inline]
607    #[doc(alias = "nextUp")]
608    #[unstable(feature = "f16", issue = "116909")]
609    #[must_use = "method returns a new number and does not mutate the original value"]
610    pub const fn next_up(self) -> Self {
611        // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
612        // denormals to zero. This is in general unsound and unsupported, but here
613        // we do our best to still produce the correct result on such targets.
614        let bits = self.to_bits();
615        if self.is_nan() || bits == Self::INFINITY.to_bits() {
616            return self;
617        }
618
619        let abs = bits & !Self::SIGN_MASK;
620        let next_bits = if abs == 0 {
621            Self::TINY_BITS
622        } else if bits == abs {
623            bits + 1
624        } else {
625            bits - 1
626        };
627        Self::from_bits(next_bits)
628    }
629
630    /// Returns the greatest number less than `self`.
631    ///
632    /// Let `TINY` be the smallest representable positive `f16`. Then,
633    ///  - if `self.is_nan()`, this returns `self`;
634    ///  - if `self` is [`INFINITY`], this returns [`MAX`];
635    ///  - if `self` is `TINY`, this returns 0.0;
636    ///  - if `self` is -0.0 or +0.0, this returns `-TINY`;
637    ///  - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
638    ///  - otherwise the unique greatest value less than `self` is returned.
639    ///
640    /// The identity `x.next_down() == -(-x).next_up()` holds for all non-NaN `x`. When `x`
641    /// is finite `x == x.next_down().next_up()` also holds.
642    ///
643    /// ```rust
644    /// #![feature(f16)]
645    /// # #[cfg(target_has_reliable_f16)] {
646    ///
647    /// let x = 1.0f16;
648    /// // Clamp value into range [0, 1).
649    /// let clamped = x.clamp(0.0, 1.0f16.next_down());
650    /// assert!(clamped < 1.0);
651    /// assert_eq!(clamped.next_up(), 1.0);
652    /// # }
653    /// ```
654    ///
655    /// This operation corresponds to IEEE-754 `nextDown`.
656    ///
657    /// [`NEG_INFINITY`]: Self::NEG_INFINITY
658    /// [`INFINITY`]: Self::INFINITY
659    /// [`MIN`]: Self::MIN
660    /// [`MAX`]: Self::MAX
661    #[inline]
662    #[doc(alias = "nextDown")]
663    #[unstable(feature = "f16", issue = "116909")]
664    #[must_use = "method returns a new number and does not mutate the original value"]
665    pub const fn next_down(self) -> Self {
666        // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
667        // denormals to zero. This is in general unsound and unsupported, but here
668        // we do our best to still produce the correct result on such targets.
669        let bits = self.to_bits();
670        if self.is_nan() || bits == Self::NEG_INFINITY.to_bits() {
671            return self;
672        }
673
674        let abs = bits & !Self::SIGN_MASK;
675        let next_bits = if abs == 0 {
676            Self::NEG_TINY_BITS
677        } else if bits == abs {
678            bits - 1
679        } else {
680            bits + 1
681        };
682        Self::from_bits(next_bits)
683    }
684
685    /// Takes the reciprocal (inverse) of a number, `1/x`.
686    ///
687    /// ```
688    /// #![feature(f16)]
689    /// # #[cfg(target_has_reliable_f16)] {
690    ///
691    /// let x = 2.0_f16;
692    /// let abs_difference = (x.recip() - (1.0 / x)).abs();
693    ///
694    /// assert!(abs_difference <= f16::EPSILON);
695    /// # }
696    /// ```
697    #[inline]
698    #[unstable(feature = "f16", issue = "116909")]
699    #[must_use = "this returns the result of the operation, without modifying the original"]
700    pub const fn recip(self) -> Self {
701        1.0 / self
702    }
703
704    /// Converts radians to degrees.
705    ///
706    /// # Unspecified precision
707    ///
708    /// The precision of this function is non-deterministic. This means it varies by platform,
709    /// Rust version, and can even differ within the same execution from one invocation to the next.
710    ///
711    /// # Examples
712    ///
713    /// ```
714    /// #![feature(f16)]
715    /// # #[cfg(target_has_reliable_f16)] {
716    ///
717    /// let angle = std::f16::consts::PI;
718    ///
719    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
720    /// assert!(abs_difference <= 0.5);
721    /// # }
722    /// ```
723    #[inline]
724    #[unstable(feature = "f16", issue = "116909")]
725    #[must_use = "this returns the result of the operation, without modifying the original"]
726    pub const fn to_degrees(self) -> Self {
727        // Use a literal to avoid double rounding, consts::PI is already rounded,
728        // and dividing would round again.
729        const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16;
730        self * PIS_IN_180
731    }
732
733    /// Converts degrees to radians.
734    ///
735    /// # Unspecified precision
736    ///
737    /// The precision of this function is non-deterministic. This means it varies by platform,
738    /// Rust version, and can even differ within the same execution from one invocation to the next.
739    ///
740    /// # Examples
741    ///
742    /// ```
743    /// #![feature(f16)]
744    /// # #[cfg(target_has_reliable_f16)] {
745    ///
746    /// let angle = 180.0f16;
747    ///
748    /// let abs_difference = (angle.to_radians() - std::f16::consts::PI).abs();
749    ///
750    /// assert!(abs_difference <= 0.01);
751    /// # }
752    /// ```
753    #[inline]
754    #[unstable(feature = "f16", issue = "116909")]
755    #[must_use = "this returns the result of the operation, without modifying the original"]
756    pub const fn to_radians(self) -> f16 {
757        // Use a literal to avoid double rounding, consts::PI is already rounded,
758        // and dividing would round again.
759        const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16;
760        self * RADS_PER_DEG
761    }
762
763    /// Returns the maximum of the two numbers, ignoring NaN.
764    ///
765    /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
766    /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
767    /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
768    /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
769    /// non-deterministically.
770    ///
771    /// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all
772    /// NaNs the same way to ensure the operation is associative. The handling of signed zeros
773    /// follows the IEEE 754-2008 semantics for `maxNum`.
774    ///
775    /// ```
776    /// #![feature(f16)]
777    /// # #[cfg(target_has_reliable_f16)] {
778    ///
779    /// let x = 1.0f16;
780    /// let y = 2.0f16;
781    ///
782    /// assert_eq!(x.max(y), y);
783    /// assert_eq!(x.max(f16::NAN), x);
784    /// # }
785    /// ```
786    #[inline]
787    #[unstable(feature = "f16", issue = "116909")]
788    #[rustc_const_unstable(feature = "f16", issue = "116909")]
789    #[must_use = "this returns the result of the comparison, without modifying either input"]
790    pub const fn max(self, other: f16) -> f16 {
791        intrinsics::maximum_number_nsz_f16(self, other)
792    }
793
794    /// Returns the minimum of the two numbers, ignoring NaN.
795    ///
796    /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
797    /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
798    /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
799    /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
800    /// non-deterministically.
801    ///
802    /// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all
803    /// NaNs the same way to ensure the operation is associative. The handling of signed zeros
804    /// follows the IEEE 754-2008 semantics for `minNum`.
805    ///
806    /// ```
807    /// #![feature(f16)]
808    /// # #[cfg(target_has_reliable_f16)] {
809    ///
810    /// let x = 1.0f16;
811    /// let y = 2.0f16;
812    ///
813    /// assert_eq!(x.min(y), x);
814    /// assert_eq!(x.min(f16::NAN), x);
815    /// # }
816    /// ```
817    #[inline]
818    #[unstable(feature = "f16", issue = "116909")]
819    #[rustc_const_unstable(feature = "f16", issue = "116909")]
820    #[must_use = "this returns the result of the comparison, without modifying either input"]
821    pub const fn min(self, other: f16) -> f16 {
822        intrinsics::minimum_number_nsz_f16(self, other)
823    }
824
825    /// Returns the maximum of the two numbers, propagating NaN.
826    ///
827    /// If at least one of the arguments is NaN, the return value is NaN, with the bit pattern
828    /// picked using the usual [rules for arithmetic operations](f32#nan-bit-patterns). Furthermore,
829    /// `-0.0` is considered to be less than `+0.0`, making this function fully deterministic for
830    /// non-NaN inputs.
831    ///
832    /// This is in contrast to [`f16::max`] which only returns NaN when *both* arguments are NaN,
833    /// and which does not reliably order `-0.0` and `+0.0`.
834    ///
835    /// This follows the IEEE 754-2019 semantics for `maximum`.
836    ///
837    /// ```
838    /// #![feature(f16)]
839    /// #![feature(float_minimum_maximum)]
840    /// # #[cfg(target_has_reliable_f16)] {
841    ///
842    /// let x = 1.0f16;
843    /// let y = 2.0f16;
844    ///
845    /// assert_eq!(x.maximum(y), y);
846    /// assert!(x.maximum(f16::NAN).is_nan());
847    /// # }
848    /// ```
849    #[inline]
850    #[unstable(feature = "f16", issue = "116909")]
851    // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
852    #[must_use = "this returns the result of the comparison, without modifying either input"]
853    pub const fn maximum(self, other: f16) -> f16 {
854        intrinsics::maximumf16(self, other)
855    }
856
857    /// Returns the minimum of the two numbers, propagating NaN.
858    ///
859    /// If at least one of the arguments is NaN, the return value is NaN, with the bit pattern
860    /// picked using the usual [rules for arithmetic operations](f32#nan-bit-patterns). Furthermore,
861    /// `-0.0` is considered to be less than `+0.0`, making this function fully deterministic for
862    /// non-NaN inputs.
863    ///
864    /// This is in contrast to [`f16::min`] which only returns NaN when *both* arguments are NaN,
865    /// and which does not reliably order `-0.0` and `+0.0`.
866    ///
867    /// This follows the IEEE 754-2019 semantics for `minimum`.
868    ///
869    /// ```
870    /// #![feature(f16)]
871    /// #![feature(float_minimum_maximum)]
872    /// # #[cfg(target_has_reliable_f16)] {
873    ///
874    /// let x = 1.0f16;
875    /// let y = 2.0f16;
876    ///
877    /// assert_eq!(x.minimum(y), x);
878    /// assert!(x.minimum(f16::NAN).is_nan());
879    /// # }
880    /// ```
881    #[inline]
882    #[unstable(feature = "f16", issue = "116909")]
883    // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
884    #[must_use = "this returns the result of the comparison, without modifying either input"]
885    pub const fn minimum(self, other: f16) -> f16 {
886        intrinsics::minimumf16(self, other)
887    }
888
889    /// Calculates the midpoint (average) between `self` and `rhs`.
890    ///
891    /// This returns NaN when *either* argument is NaN or if a combination of
892    /// +inf and -inf is provided as arguments.
893    ///
894    /// # Examples
895    ///
896    /// ```
897    /// #![feature(f16)]
898    /// # #[cfg(target_has_reliable_f16)] {
899    ///
900    /// assert_eq!(1f16.midpoint(4.0), 2.5);
901    /// assert_eq!((-5.5f16).midpoint(8.0), 1.25);
902    /// # }
903    /// ```
904    #[inline]
905    #[doc(alias = "average")]
906    #[unstable(feature = "f16", issue = "116909")]
907    #[rustc_const_unstable(feature = "f16", issue = "116909")]
908    #[must_use = "this returns the result of the operation, \
909                  without modifying the original"]
910    pub const fn midpoint(self, other: f16) -> f16 {
911        const HI: f16 = f16::MAX / 2.;
912
913        let (a, b) = (self, other);
914        let abs_a = a.abs();
915        let abs_b = b.abs();
916
917        if abs_a <= HI && abs_b <= HI {
918            // Overflow is impossible
919            (a + b) / 2.
920        } else {
921            (a / 2.) + (b / 2.)
922        }
923    }
924
925    /// Rounds toward zero and converts to any primitive integer type,
926    /// assuming that the value is finite and fits in that type.
927    ///
928    /// ```
929    /// #![feature(f16)]
930    /// # #[cfg(target_has_reliable_f16)] {
931    ///
932    /// let value = 4.6_f16;
933    /// let rounded = unsafe { value.to_int_unchecked::<u16>() };
934    /// assert_eq!(rounded, 4);
935    ///
936    /// let value = -128.9_f16;
937    /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
938    /// assert_eq!(rounded, i8::MIN);
939    /// # }
940    /// ```
941    ///
942    /// # Safety
943    ///
944    /// The value must:
945    ///
946    /// * Not be `NaN`
947    /// * Not be infinite
948    /// * Be representable in the return type `Int`, after truncating off its fractional part
949    #[inline]
950    #[unstable(feature = "f16", issue = "116909")]
951    #[must_use = "this returns the result of the operation, without modifying the original"]
952    pub unsafe fn to_int_unchecked<Int>(self) -> Int
953    where
954        Self: FloatToInt<Int>,
955    {
956        // SAFETY: the caller must uphold the safety contract for
957        // `FloatToInt::to_int_unchecked`.
958        unsafe { FloatToInt::<Int>::to_int_unchecked(self) }
959    }
960
961    /// Raw transmutation to `u16`.
962    ///
963    /// This is currently identical to `transmute::<f16, u16>(self)` on all platforms.
964    ///
965    /// See [`from_bits`](#method.from_bits) for some discussion of the
966    /// portability of this operation (there are almost no issues).
967    ///
968    /// Note that this function is distinct from `as` casting, which attempts to
969    /// preserve the *numeric* value, and not the bitwise value.
970    ///
971    /// ```
972    /// #![feature(f16)]
973    /// # #[cfg(target_has_reliable_f16)] {
974    ///
975    /// assert_ne!((1f16).to_bits(), 1f16 as u16); // to_bits() is not casting!
976    /// assert_eq!((12.5f16).to_bits(), 0x4a40);
977    /// # }
978    /// ```
979    #[inline]
980    #[unstable(feature = "f16", issue = "116909")]
981    #[must_use = "this returns the result of the operation, without modifying the original"]
982    #[allow(unnecessary_transmutes)]
983    #[ferrocene::prevalidated]
984    pub const fn to_bits(self) -> u16 {
985        // SAFETY: `u16` is a plain old datatype so we can always transmute to it.
986        unsafe { mem::transmute(self) }
987    }
988
989    /// Raw transmutation from `u16`.
990    ///
991    /// This is currently identical to `transmute::<u16, f16>(v)` on all platforms.
992    /// It turns out this is incredibly portable, for two reasons:
993    ///
994    /// * Floats and Ints have the same endianness on all supported platforms.
995    /// * IEEE 754 very precisely specifies the bit layout of floats.
996    ///
997    /// However there is one caveat: prior to the 2008 version of IEEE 754, how
998    /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
999    /// (notably x86 and ARM) picked the interpretation that was ultimately
1000    /// standardized in 2008, but some didn't (notably MIPS). As a result, all
1001    /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
1002    ///
1003    /// Rather than trying to preserve signaling-ness cross-platform, this
1004    /// implementation favors preserving the exact bits. This means that
1005    /// any payloads encoded in NaNs will be preserved even if the result of
1006    /// this method is sent over the network from an x86 machine to a MIPS one.
1007    ///
1008    /// If the results of this method are only manipulated by the same
1009    /// architecture that produced them, then there is no portability concern.
1010    ///
1011    /// If the input isn't NaN, then there is no portability concern.
1012    ///
1013    /// If you don't care about signalingness (very likely), then there is no
1014    /// portability concern.
1015    ///
1016    /// Note that this function is distinct from `as` casting, which attempts to
1017    /// preserve the *numeric* value, and not the bitwise value.
1018    ///
1019    /// ```
1020    /// #![feature(f16)]
1021    /// # #[cfg(target_has_reliable_f16)] {
1022    ///
1023    /// let v = f16::from_bits(0x4a40);
1024    /// assert_eq!(v, 12.5);
1025    /// # }
1026    /// ```
1027    #[inline]
1028    #[must_use]
1029    #[unstable(feature = "f16", issue = "116909")]
1030    #[allow(unnecessary_transmutes)]
1031    #[ferrocene::prevalidated]
1032    pub const fn from_bits(v: u16) -> Self {
1033        // It turns out the safety issues with sNaN were overblown! Hooray!
1034        // SAFETY: `u16` is a plain old datatype so we can always transmute from it.
1035        unsafe { mem::transmute(v) }
1036    }
1037
1038    /// Returns the memory representation of this floating point number as a byte array in
1039    /// big-endian (network) byte order.
1040    ///
1041    /// See [`from_bits`](Self::from_bits) for some discussion of the
1042    /// portability of this operation (there are almost no issues).
1043    ///
1044    /// # Examples
1045    ///
1046    /// ```
1047    /// #![feature(f16)]
1048    /// # #[cfg(target_has_reliable_f16)] {
1049    ///
1050    /// let bytes = 12.5f16.to_be_bytes();
1051    /// assert_eq!(bytes, [0x4a, 0x40]);
1052    /// # }
1053    /// ```
1054    #[inline]
1055    #[unstable(feature = "f16", issue = "116909")]
1056    #[must_use = "this returns the result of the operation, without modifying the original"]
1057    pub const fn to_be_bytes(self) -> [u8; 2] {
1058        self.to_bits().to_be_bytes()
1059    }
1060
1061    /// Returns the memory representation of this floating point number as a byte array in
1062    /// little-endian byte order.
1063    ///
1064    /// See [`from_bits`](Self::from_bits) for some discussion of the
1065    /// portability of this operation (there are almost no issues).
1066    ///
1067    /// # Examples
1068    ///
1069    /// ```
1070    /// #![feature(f16)]
1071    /// # #[cfg(target_has_reliable_f16)] {
1072    ///
1073    /// let bytes = 12.5f16.to_le_bytes();
1074    /// assert_eq!(bytes, [0x40, 0x4a]);
1075    /// # }
1076    /// ```
1077    #[inline]
1078    #[unstable(feature = "f16", issue = "116909")]
1079    #[must_use = "this returns the result of the operation, without modifying the original"]
1080    pub const fn to_le_bytes(self) -> [u8; 2] {
1081        self.to_bits().to_le_bytes()
1082    }
1083
1084    /// Returns the memory representation of this floating point number as a byte array in
1085    /// native byte order.
1086    ///
1087    /// As the target platform's native endianness is used, portable code
1088    /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
1089    ///
1090    /// [`to_be_bytes`]: f16::to_be_bytes
1091    /// [`to_le_bytes`]: f16::to_le_bytes
1092    ///
1093    /// See [`from_bits`](Self::from_bits) for some discussion of the
1094    /// portability of this operation (there are almost no issues).
1095    ///
1096    /// # Examples
1097    ///
1098    /// ```
1099    /// #![feature(f16)]
1100    /// # #[cfg(target_has_reliable_f16)] {
1101    ///
1102    /// let bytes = 12.5f16.to_ne_bytes();
1103    /// assert_eq!(
1104    ///     bytes,
1105    ///     if cfg!(target_endian = "big") {
1106    ///         [0x4a, 0x40]
1107    ///     } else {
1108    ///         [0x40, 0x4a]
1109    ///     }
1110    /// );
1111    /// # }
1112    /// ```
1113    #[inline]
1114    #[unstable(feature = "f16", issue = "116909")]
1115    #[must_use = "this returns the result of the operation, without modifying the original"]
1116    pub const fn to_ne_bytes(self) -> [u8; 2] {
1117        self.to_bits().to_ne_bytes()
1118    }
1119
1120    /// Creates a floating point value from its representation as a byte array in big endian.
1121    ///
1122    /// See [`from_bits`](Self::from_bits) for some discussion of the
1123    /// portability of this operation (there are almost no issues).
1124    ///
1125    /// # Examples
1126    ///
1127    /// ```
1128    /// #![feature(f16)]
1129    /// # #[cfg(target_has_reliable_f16)] {
1130    ///
1131    /// let value = f16::from_be_bytes([0x4a, 0x40]);
1132    /// assert_eq!(value, 12.5);
1133    /// # }
1134    /// ```
1135    #[inline]
1136    #[must_use]
1137    #[unstable(feature = "f16", issue = "116909")]
1138    pub const fn from_be_bytes(bytes: [u8; 2]) -> Self {
1139        Self::from_bits(u16::from_be_bytes(bytes))
1140    }
1141
1142    /// Creates a floating point value from its representation as a byte array in little endian.
1143    ///
1144    /// See [`from_bits`](Self::from_bits) for some discussion of the
1145    /// portability of this operation (there are almost no issues).
1146    ///
1147    /// # Examples
1148    ///
1149    /// ```
1150    /// #![feature(f16)]
1151    /// # #[cfg(target_has_reliable_f16)] {
1152    ///
1153    /// let value = f16::from_le_bytes([0x40, 0x4a]);
1154    /// assert_eq!(value, 12.5);
1155    /// # }
1156    /// ```
1157    #[inline]
1158    #[must_use]
1159    #[unstable(feature = "f16", issue = "116909")]
1160    pub const fn from_le_bytes(bytes: [u8; 2]) -> Self {
1161        Self::from_bits(u16::from_le_bytes(bytes))
1162    }
1163
1164    /// Creates a floating point value from its representation as a byte array in native endian.
1165    ///
1166    /// As the target platform's native endianness is used, portable code
1167    /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
1168    /// appropriate instead.
1169    ///
1170    /// [`from_be_bytes`]: f16::from_be_bytes
1171    /// [`from_le_bytes`]: f16::from_le_bytes
1172    ///
1173    /// See [`from_bits`](Self::from_bits) for some discussion of the
1174    /// portability of this operation (there are almost no issues).
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```
1179    /// #![feature(f16)]
1180    /// # #[cfg(target_has_reliable_f16)] {
1181    ///
1182    /// let value = f16::from_ne_bytes(if cfg!(target_endian = "big") {
1183    ///     [0x4a, 0x40]
1184    /// } else {
1185    ///     [0x40, 0x4a]
1186    /// });
1187    /// assert_eq!(value, 12.5);
1188    /// # }
1189    /// ```
1190    #[inline]
1191    #[must_use]
1192    #[unstable(feature = "f16", issue = "116909")]
1193    pub const fn from_ne_bytes(bytes: [u8; 2]) -> Self {
1194        Self::from_bits(u16::from_ne_bytes(bytes))
1195    }
1196
1197    /// Returns the ordering between `self` and `other`.
1198    ///
1199    /// Unlike the standard partial comparison between floating point numbers,
1200    /// this comparison always produces an ordering in accordance to
1201    /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
1202    /// floating point standard. The values are ordered in the following sequence:
1203    ///
1204    /// - negative quiet NaN
1205    /// - negative signaling NaN
1206    /// - negative infinity
1207    /// - negative numbers
1208    /// - negative subnormal numbers
1209    /// - negative zero
1210    /// - positive zero
1211    /// - positive subnormal numbers
1212    /// - positive numbers
1213    /// - positive infinity
1214    /// - positive signaling NaN
1215    /// - positive quiet NaN.
1216    ///
1217    /// The ordering established by this function does not always agree with the
1218    /// [`PartialOrd`] and [`PartialEq`] implementations of `f16`. For example,
1219    /// they consider negative and positive zero equal, while `total_cmp`
1220    /// doesn't.
1221    ///
1222    /// The interpretation of the signaling NaN bit follows the definition in
1223    /// the IEEE 754 standard, which may not match the interpretation by some of
1224    /// the older, non-conformant (e.g. MIPS) hardware implementations.
1225    ///
1226    /// # Example
1227    ///
1228    /// ```
1229    /// #![feature(f16)]
1230    /// # #[cfg(target_has_reliable_f16)] {
1231    ///
1232    /// struct GoodBoy {
1233    ///     name: &'static str,
1234    ///     weight: f16,
1235    /// }
1236    ///
1237    /// let mut bois = vec![
1238    ///     GoodBoy { name: "Pucci", weight: 0.1 },
1239    ///     GoodBoy { name: "Woofer", weight: 99.0 },
1240    ///     GoodBoy { name: "Yapper", weight: 10.0 },
1241    ///     GoodBoy { name: "Chonk", weight: f16::INFINITY },
1242    ///     GoodBoy { name: "Abs. Unit", weight: f16::NAN },
1243    ///     GoodBoy { name: "Floaty", weight: -5.0 },
1244    /// ];
1245    ///
1246    /// bois.sort_by(|a, b| a.weight.total_cmp(&b.weight));
1247    ///
1248    /// // `f16::NAN` could be positive or negative, which will affect the sort order.
1249    /// if f16::NAN.is_sign_negative() {
1250    ///     bois.into_iter().map(|b| b.weight)
1251    ///         .zip([f16::NAN, -5.0, 0.1, 10.0, 99.0, f16::INFINITY].iter())
1252    ///         .for_each(|(a, b)| assert_eq!(a.to_bits(), b.to_bits()))
1253    /// } else {
1254    ///     bois.into_iter().map(|b| b.weight)
1255    ///         .zip([-5.0, 0.1, 10.0, 99.0, f16::INFINITY, f16::NAN].iter())
1256    ///         .for_each(|(a, b)| assert_eq!(a.to_bits(), b.to_bits()))
1257    /// }
1258    /// # }
1259    /// ```
1260    #[inline]
1261    #[must_use]
1262    #[unstable(feature = "f16", issue = "116909")]
1263    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
1264    pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
1265        let mut left = self.to_bits() as i16;
1266        let mut right = other.to_bits() as i16;
1267
1268        // In case of negatives, flip all the bits except the sign
1269        // to achieve a similar layout as two's complement integers
1270        //
1271        // Why does this work? IEEE 754 floats consist of three fields:
1272        // Sign bit, exponent and mantissa. The set of exponent and mantissa
1273        // fields as a whole have the property that their bitwise order is
1274        // equal to the numeric magnitude where the magnitude is defined.
1275        // The magnitude is not normally defined on NaN values, but
1276        // IEEE 754 totalOrder defines the NaN values also to follow the
1277        // bitwise order. This leads to order explained in the doc comment.
1278        // However, the representation of magnitude is the same for negative
1279        // and positive numbers – only the sign bit is different.
1280        // To easily compare the floats as signed integers, we need to
1281        // flip the exponent and mantissa bits in case of negative numbers.
1282        // We effectively convert the numbers to "two's complement" form.
1283        //
1284        // To do the flipping, we construct a mask and XOR against it.
1285        // We branchlessly calculate an "all-ones except for the sign bit"
1286        // mask from negative-signed values: right shifting sign-extends
1287        // the integer, so we "fill" the mask with sign bits, and then
1288        // convert to unsigned to push one more zero bit.
1289        // On positive values, the mask is all zeros, so it's a no-op.
1290        left ^= (((left >> 15) as u16) >> 1) as i16;
1291        right ^= (((right >> 15) as u16) >> 1) as i16;
1292
1293        left.cmp(&right)
1294    }
1295
1296    /// Restrict a value to a certain interval unless it is NaN.
1297    ///
1298    /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
1299    /// less than `min`. Otherwise this returns `self`.
1300    ///
1301    /// Note that this function returns NaN if the initial value was NaN as
1302    /// well. If the result is zero and among the three inputs `self`, `min`, and `max` there are
1303    /// zeros with different sign, either `0.0` or `-0.0` is returned non-deterministically.
1304    ///
1305    /// # Panics
1306    ///
1307    /// Panics if `min > max`, `min` is NaN, or `max` is NaN.
1308    ///
1309    /// # Examples
1310    ///
1311    /// ```
1312    /// #![feature(f16)]
1313    /// # #[cfg(target_has_reliable_f16)] {
1314    ///
1315    /// assert!((-3.0f16).clamp(-2.0, 1.0) == -2.0);
1316    /// assert!((0.0f16).clamp(-2.0, 1.0) == 0.0);
1317    /// assert!((2.0f16).clamp(-2.0, 1.0) == 1.0);
1318    /// assert!((f16::NAN).clamp(-2.0, 1.0).is_nan());
1319    ///
1320    /// // These always returns zero, but the sign (which is ignored by `==`) is non-deterministic.
1321    /// assert!((0.0f16).clamp(-0.0, -0.0) == 0.0);
1322    /// assert!((1.0f16).clamp(-0.0, 0.0) == 0.0);
1323    /// // This is definitely a negative zero.
1324    /// assert!((-1.0f16).clamp(-0.0, 1.0).is_sign_negative());
1325    /// # }
1326    /// ```
1327    #[inline]
1328    #[unstable(feature = "f16", issue = "116909")]
1329    #[must_use = "method returns a new number and does not mutate the original value"]
1330    pub const fn clamp(mut self, min: f16, max: f16) -> f16 {
1331        const_assert!(
1332            min <= max,
1333            "min > max, or either was NaN",
1334            "min > max, or either was NaN. min = {min:?}, max = {max:?}",
1335            min: f16,
1336            max: f16,
1337        );
1338
1339        if self < min {
1340            self = min;
1341        }
1342        if self > max {
1343            self = max;
1344        }
1345        self
1346    }
1347
1348    /// Clamps this number to a symmetric range centered around zero.
1349    ///
1350    /// The method clamps the number's magnitude (absolute value) to be at most `limit`.
1351    ///
1352    /// This is functionally equivalent to `self.clamp(-limit, limit)`, but is more
1353    /// explicit about the intent.
1354    ///
1355    /// # Panics
1356    ///
1357    /// Panics if `limit` is negative or NaN, as this indicates a logic error.
1358    ///
1359    /// # Examples
1360    ///
1361    /// ```
1362    /// #![feature(f16)]
1363    /// #![feature(clamp_magnitude)]
1364    /// # #[cfg(target_has_reliable_f16)] {
1365    /// assert_eq!(5.0f16.clamp_magnitude(3.0), 3.0);
1366    /// assert_eq!((-5.0f16).clamp_magnitude(3.0), -3.0);
1367    /// assert_eq!(2.0f16.clamp_magnitude(3.0), 2.0);
1368    /// assert_eq!((-2.0f16).clamp_magnitude(3.0), -2.0);
1369    /// # }
1370    /// ```
1371    #[inline]
1372    #[unstable(feature = "clamp_magnitude", issue = "148519")]
1373    #[must_use = "this returns the clamped value and does not modify the original"]
1374    pub fn clamp_magnitude(self, limit: f16) -> f16 {
1375        assert!(limit >= 0.0, "limit must be non-negative");
1376        let limit = limit.abs(); // Canonicalises -0.0 to 0.0
1377        self.clamp(-limit, limit)
1378    }
1379
1380    /// Computes the absolute value of `self`.
1381    ///
1382    /// This function always returns the precise result.
1383    ///
1384    /// # Examples
1385    ///
1386    /// ```
1387    /// #![feature(f16)]
1388    /// # #[cfg(target_has_reliable_f16_math)] {
1389    ///
1390    /// let x = 3.5_f16;
1391    /// let y = -3.5_f16;
1392    ///
1393    /// assert_eq!(x.abs(), x);
1394    /// assert_eq!(y.abs(), -y);
1395    ///
1396    /// assert!(f16::NAN.abs().is_nan());
1397    /// # }
1398    /// ```
1399    #[inline]
1400    #[unstable(feature = "f16", issue = "116909")]
1401    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1402    #[must_use = "method returns a new number and does not mutate the original value"]
1403    #[ferrocene::prevalidated]
1404    pub const fn abs(self) -> Self {
1405        intrinsics::fabs(self)
1406    }
1407
1408    /// Returns a number that represents the sign of `self`.
1409    ///
1410    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
1411    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
1412    /// - NaN if the number is NaN
1413    ///
1414    /// # Examples
1415    ///
1416    /// ```
1417    /// #![feature(f16)]
1418    /// # #[cfg(target_has_reliable_f16)] {
1419    ///
1420    /// let f = 3.5_f16;
1421    ///
1422    /// assert_eq!(f.signum(), 1.0);
1423    /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0);
1424    ///
1425    /// assert!(f16::NAN.signum().is_nan());
1426    /// # }
1427    /// ```
1428    #[inline]
1429    #[unstable(feature = "f16", issue = "116909")]
1430    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1431    #[must_use = "method returns a new number and does not mutate the original value"]
1432    pub const fn signum(self) -> f16 {
1433        if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
1434    }
1435
1436    /// Returns a number composed of the magnitude of `self` and the sign of
1437    /// `sign`.
1438    ///
1439    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
1440    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
1441    /// returned.
1442    ///
1443    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
1444    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
1445    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
1446    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
1447    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
1448    /// info.
1449    ///
1450    /// # Examples
1451    ///
1452    /// ```
1453    /// #![feature(f16)]
1454    /// # #[cfg(target_has_reliable_f16_math)] {
1455    ///
1456    /// let f = 3.5_f16;
1457    ///
1458    /// assert_eq!(f.copysign(0.42), 3.5_f16);
1459    /// assert_eq!(f.copysign(-0.42), -3.5_f16);
1460    /// assert_eq!((-f).copysign(0.42), 3.5_f16);
1461    /// assert_eq!((-f).copysign(-0.42), -3.5_f16);
1462    ///
1463    /// assert!(f16::NAN.copysign(1.0).is_nan());
1464    /// # }
1465    /// ```
1466    #[inline]
1467    #[unstable(feature = "f16", issue = "116909")]
1468    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1469    #[must_use = "method returns a new number and does not mutate the original value"]
1470    pub const fn copysign(self, sign: f16) -> f16 {
1471        intrinsics::copysignf16(self, sign)
1472    }
1473
1474    /// Float addition that allows optimizations based on algebraic rules.
1475    ///
1476    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
1477    #[must_use = "method returns a new number and does not mutate the original value"]
1478    #[unstable(feature = "float_algebraic", issue = "136469")]
1479    #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
1480    #[inline]
1481    pub const fn algebraic_add(self, rhs: f16) -> f16 {
1482        intrinsics::fadd_algebraic(self, rhs)
1483    }
1484
1485    /// Float subtraction that allows optimizations based on algebraic rules.
1486    ///
1487    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
1488    #[must_use = "method returns a new number and does not mutate the original value"]
1489    #[unstable(feature = "float_algebraic", issue = "136469")]
1490    #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
1491    #[inline]
1492    pub const fn algebraic_sub(self, rhs: f16) -> f16 {
1493        intrinsics::fsub_algebraic(self, rhs)
1494    }
1495
1496    /// Float multiplication that allows optimizations based on algebraic rules.
1497    ///
1498    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
1499    #[must_use = "method returns a new number and does not mutate the original value"]
1500    #[unstable(feature = "float_algebraic", issue = "136469")]
1501    #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
1502    #[inline]
1503    pub const fn algebraic_mul(self, rhs: f16) -> f16 {
1504        intrinsics::fmul_algebraic(self, rhs)
1505    }
1506
1507    /// Float division that allows optimizations based on algebraic rules.
1508    ///
1509    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
1510    #[must_use = "method returns a new number and does not mutate the original value"]
1511    #[unstable(feature = "float_algebraic", issue = "136469")]
1512    #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
1513    #[inline]
1514    pub const fn algebraic_div(self, rhs: f16) -> f16 {
1515        intrinsics::fdiv_algebraic(self, rhs)
1516    }
1517
1518    /// Float remainder that allows optimizations based on algebraic rules.
1519    ///
1520    /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
1521    #[must_use = "method returns a new number and does not mutate the original value"]
1522    #[unstable(feature = "float_algebraic", issue = "136469")]
1523    #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
1524    #[inline]
1525    pub const fn algebraic_rem(self, rhs: f16) -> f16 {
1526        intrinsics::frem_algebraic(self, rhs)
1527    }
1528}
1529
1530// Functions in this module fall into `core_float_math`
1531// #[unstable(feature = "core_float_math", issue = "137578")]
1532#[cfg(not(test))]
1533#[doc(test(attr(
1534    feature(cfg_target_has_reliable_f16_f128),
1535    expect(internal_features),
1536    allow(unused_features)
1537)))]
1538impl f16 {
1539    /// Returns the largest integer less than or equal to `self`.
1540    ///
1541    /// This function always returns the precise result.
1542    ///
1543    /// # Examples
1544    ///
1545    /// ```
1546    /// #![feature(f16)]
1547    /// # #[cfg(not(miri))]
1548    /// # #[cfg(target_has_reliable_f16)] {
1549    ///
1550    /// let f = 3.7_f16;
1551    /// let g = 3.0_f16;
1552    /// let h = -3.7_f16;
1553    ///
1554    /// assert_eq!(f.floor(), 3.0);
1555    /// assert_eq!(g.floor(), 3.0);
1556    /// assert_eq!(h.floor(), -4.0);
1557    /// # }
1558    /// ```
1559    #[inline]
1560    #[rustc_allow_incoherent_impl]
1561    #[unstable(feature = "f16", issue = "116909")]
1562    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1563    #[must_use = "method returns a new number and does not mutate the original value"]
1564    pub const fn floor(self) -> f16 {
1565        intrinsics::floorf16(self)
1566    }
1567
1568    /// Returns the smallest integer greater than or equal to `self`.
1569    ///
1570    /// This function always returns the precise result.
1571    ///
1572    /// # Examples
1573    ///
1574    /// ```
1575    /// #![feature(f16)]
1576    /// # #[cfg(not(miri))]
1577    /// # #[cfg(target_has_reliable_f16)] {
1578    ///
1579    /// let f = 3.01_f16;
1580    /// let g = 4.0_f16;
1581    ///
1582    /// assert_eq!(f.ceil(), 4.0);
1583    /// assert_eq!(g.ceil(), 4.0);
1584    /// # }
1585    /// ```
1586    #[inline]
1587    #[doc(alias = "ceiling")]
1588    #[rustc_allow_incoherent_impl]
1589    #[unstable(feature = "f16", issue = "116909")]
1590    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1591    #[must_use = "method returns a new number and does not mutate the original value"]
1592    pub const fn ceil(self) -> f16 {
1593        intrinsics::ceilf16(self)
1594    }
1595
1596    /// Returns the nearest integer to `self`. If a value is half-way between two
1597    /// integers, round away from `0.0`.
1598    ///
1599    /// This function always returns the precise result.
1600    ///
1601    /// # Examples
1602    ///
1603    /// ```
1604    /// #![feature(f16)]
1605    /// # #[cfg(not(miri))]
1606    /// # #[cfg(target_has_reliable_f16)] {
1607    ///
1608    /// let f = 3.3_f16;
1609    /// let g = -3.3_f16;
1610    /// let h = -3.7_f16;
1611    /// let i = 3.5_f16;
1612    /// let j = 4.5_f16;
1613    ///
1614    /// assert_eq!(f.round(), 3.0);
1615    /// assert_eq!(g.round(), -3.0);
1616    /// assert_eq!(h.round(), -4.0);
1617    /// assert_eq!(i.round(), 4.0);
1618    /// assert_eq!(j.round(), 5.0);
1619    /// # }
1620    /// ```
1621    #[inline]
1622    #[rustc_allow_incoherent_impl]
1623    #[unstable(feature = "f16", issue = "116909")]
1624    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1625    #[must_use = "method returns a new number and does not mutate the original value"]
1626    pub const fn round(self) -> f16 {
1627        intrinsics::roundf16(self)
1628    }
1629
1630    /// Returns the nearest integer to a number. Rounds half-way cases to the number
1631    /// with an even least significant digit.
1632    ///
1633    /// This function always returns the precise result.
1634    ///
1635    /// # Examples
1636    ///
1637    /// ```
1638    /// #![feature(f16)]
1639    /// # #[cfg(not(miri))]
1640    /// # #[cfg(target_has_reliable_f16)] {
1641    ///
1642    /// let f = 3.3_f16;
1643    /// let g = -3.3_f16;
1644    /// let h = 3.5_f16;
1645    /// let i = 4.5_f16;
1646    ///
1647    /// assert_eq!(f.round_ties_even(), 3.0);
1648    /// assert_eq!(g.round_ties_even(), -3.0);
1649    /// assert_eq!(h.round_ties_even(), 4.0);
1650    /// assert_eq!(i.round_ties_even(), 4.0);
1651    /// # }
1652    /// ```
1653    #[inline]
1654    #[rustc_allow_incoherent_impl]
1655    #[unstable(feature = "f16", issue = "116909")]
1656    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1657    #[must_use = "method returns a new number and does not mutate the original value"]
1658    pub const fn round_ties_even(self) -> f16 {
1659        intrinsics::round_ties_even_f16(self)
1660    }
1661
1662    /// Returns the integer part of `self`.
1663    /// This means that non-integer numbers are always truncated towards zero.
1664    ///
1665    /// This function always returns the precise result.
1666    ///
1667    /// # Examples
1668    ///
1669    /// ```
1670    /// #![feature(f16)]
1671    /// # #[cfg(not(miri))]
1672    /// # #[cfg(target_has_reliable_f16)] {
1673    ///
1674    /// let f = 3.7_f16;
1675    /// let g = 3.0_f16;
1676    /// let h = -3.7_f16;
1677    ///
1678    /// assert_eq!(f.trunc(), 3.0);
1679    /// assert_eq!(g.trunc(), 3.0);
1680    /// assert_eq!(h.trunc(), -3.0);
1681    /// # }
1682    /// ```
1683    #[inline]
1684    #[doc(alias = "truncate")]
1685    #[rustc_allow_incoherent_impl]
1686    #[unstable(feature = "f16", issue = "116909")]
1687    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1688    #[must_use = "method returns a new number and does not mutate the original value"]
1689    pub const fn trunc(self) -> f16 {
1690        intrinsics::truncf16(self)
1691    }
1692
1693    /// Returns the fractional part of `self`.
1694    ///
1695    /// This function always returns the precise result.
1696    ///
1697    /// # Examples
1698    ///
1699    /// ```
1700    /// #![feature(f16)]
1701    /// # #[cfg(not(miri))]
1702    /// # #[cfg(target_has_reliable_f16)] {
1703    ///
1704    /// let x = 3.6_f16;
1705    /// let y = -3.6_f16;
1706    /// let abs_difference_x = (x.fract() - 0.6).abs();
1707    /// let abs_difference_y = (y.fract() - (-0.6)).abs();
1708    ///
1709    /// assert!(abs_difference_x <= f16::EPSILON);
1710    /// assert!(abs_difference_y <= f16::EPSILON);
1711    /// # }
1712    /// ```
1713    #[inline]
1714    #[rustc_allow_incoherent_impl]
1715    #[unstable(feature = "f16", issue = "116909")]
1716    #[rustc_const_unstable(feature = "f16", issue = "116909")]
1717    #[must_use = "method returns a new number and does not mutate the original value"]
1718    pub const fn fract(self) -> f16 {
1719        self - self.trunc()
1720    }
1721
1722    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
1723    /// error, yielding a more accurate result than an unfused multiply-add.
1724    ///
1725    /// Using `mul_add` *may* be more performant than an unfused multiply-add if
1726    /// the target architecture has a dedicated `fma` CPU instruction. However,
1727    /// this is not always true, and will be heavily dependant on designing
1728    /// algorithms with specific target hardware in mind.
1729    ///
1730    /// # Precision
1731    ///
1732    /// The result of this operation is guaranteed to be the rounded
1733    /// infinite-precision result. It is specified by IEEE 754 as
1734    /// `fusedMultiplyAdd` and guaranteed not to change.
1735    ///
1736    /// # Examples
1737    ///
1738    /// ```
1739    /// #![feature(f16)]
1740    /// # #[cfg(not(miri))]
1741    /// # #[cfg(target_has_reliable_f16)] {
1742    ///
1743    /// let m = 10.0_f16;
1744    /// let x = 4.0_f16;
1745    /// let b = 60.0_f16;
1746    ///
1747    /// assert_eq!(m.mul_add(x, b), 100.0);
1748    /// assert_eq!(m * x + b, 100.0);
1749    ///
1750    /// let one_plus_eps = 1.0_f16 + f16::EPSILON;
1751    /// let one_minus_eps = 1.0_f16 - f16::EPSILON;
1752    /// let minus_one = -1.0_f16;
1753    ///
1754    /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
1755    /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f16::EPSILON * f16::EPSILON);
1756    /// // Different rounding with the non-fused multiply and add.
1757    /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0);
1758    /// # }
1759    /// ```
1760    #[inline]
1761    #[rustc_allow_incoherent_impl]
1762    #[unstable(feature = "f16", issue = "116909")]
1763    #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")]
1764    #[must_use = "method returns a new number and does not mutate the original value"]
1765    pub const fn mul_add(self, a: f16, b: f16) -> f16 {
1766        intrinsics::fmaf16(self, a, b)
1767    }
1768
1769    /// Calculates Euclidean division, the matching method for `rem_euclid`.
1770    ///
1771    /// This computes the integer `n` such that
1772    /// `self = n * rhs + self.rem_euclid(rhs)`.
1773    /// In other words, the result is `self / rhs` rounded to the integer `n`
1774    /// such that `self >= n * rhs`.
1775    ///
1776    /// # Precision
1777    ///
1778    /// The result of this operation is guaranteed to be the rounded
1779    /// infinite-precision result.
1780    ///
1781    /// # Examples
1782    ///
1783    /// ```
1784    /// #![feature(f16)]
1785    /// # #[cfg(not(miri))]
1786    /// # #[cfg(target_has_reliable_f16)] {
1787    ///
1788    /// let a: f16 = 7.0;
1789    /// let b = 4.0;
1790    /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
1791    /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
1792    /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
1793    /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
1794    /// # }
1795    /// ```
1796    #[inline]
1797    #[rustc_allow_incoherent_impl]
1798    #[unstable(feature = "f16", issue = "116909")]
1799    #[must_use = "method returns a new number and does not mutate the original value"]
1800    pub fn div_euclid(self, rhs: f16) -> f16 {
1801        let q = (self / rhs).trunc();
1802        if self % rhs < 0.0 {
1803            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
1804        }
1805        q
1806    }
1807
1808    /// Calculates the least nonnegative remainder of `self` when
1809    /// divided by `rhs`.
1810    ///
1811    /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
1812    /// most cases. However, due to a floating point round-off error it can
1813    /// result in `r == rhs.abs()`, violating the mathematical definition, if
1814    /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
1815    /// This result is not an element of the function's codomain, but it is the
1816    /// closest floating point number in the real numbers and thus fulfills the
1817    /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
1818    /// approximately.
1819    ///
1820    /// # Precision
1821    ///
1822    /// The result of this operation is guaranteed to be the rounded
1823    /// infinite-precision result.
1824    ///
1825    /// # Examples
1826    ///
1827    /// ```
1828    /// #![feature(f16)]
1829    /// # #[cfg(not(miri))]
1830    /// # #[cfg(target_has_reliable_f16)] {
1831    ///
1832    /// let a: f16 = 7.0;
1833    /// let b = 4.0;
1834    /// assert_eq!(a.rem_euclid(b), 3.0);
1835    /// assert_eq!((-a).rem_euclid(b), 1.0);
1836    /// assert_eq!(a.rem_euclid(-b), 3.0);
1837    /// assert_eq!((-a).rem_euclid(-b), 1.0);
1838    /// // limitation due to round-off error
1839    /// assert!((-f16::EPSILON).rem_euclid(3.0) != 0.0);
1840    /// # }
1841    /// ```
1842    #[inline]
1843    #[rustc_allow_incoherent_impl]
1844    #[doc(alias = "modulo", alias = "mod")]
1845    #[unstable(feature = "f16", issue = "116909")]
1846    #[must_use = "method returns a new number and does not mutate the original value"]
1847    pub fn rem_euclid(self, rhs: f16) -> f16 {
1848        let r = self % rhs;
1849        if r < 0.0 { r + rhs.abs() } else { r }
1850    }
1851
1852    /// Raises a number to an integer power.
1853    ///
1854    /// Using this function is generally faster than using `powf`.
1855    /// It might have a different sequence of rounding operations than `powf`,
1856    /// so the results are not guaranteed to agree.
1857    ///
1858    /// Note that this function is special in that it can return non-NaN results for NaN inputs. For
1859    /// example, `f16::powi(f16::NAN, 0)` returns `1.0`. However, if an input is a *signaling*
1860    /// NaN, then the result is non-deterministically either a NaN or the result that the
1861    /// corresponding quiet NaN would produce.
1862    ///
1863    /// # Unspecified precision
1864    ///
1865    /// The precision of this function is non-deterministic. This means it varies by platform,
1866    /// Rust version, and can even differ within the same execution from one invocation to the next.
1867    ///
1868    /// # Examples
1869    ///
1870    /// ```
1871    /// #![feature(f16)]
1872    /// # #[cfg(not(miri))]
1873    /// # #[cfg(target_has_reliable_f16)] {
1874    ///
1875    /// let x = 2.0_f16;
1876    /// let abs_difference = (x.powi(2) - (x * x)).abs();
1877    /// assert!(abs_difference <= f16::EPSILON);
1878    ///
1879    /// assert_eq!(f16::powi(f16::NAN, 0), 1.0);
1880    /// assert_eq!(f16::powi(0.0, 0), 1.0);
1881    /// # }
1882    /// ```
1883    #[inline]
1884    #[rustc_allow_incoherent_impl]
1885    #[unstable(feature = "f16", issue = "116909")]
1886    #[must_use = "method returns a new number and does not mutate the original value"]
1887    pub fn powi(self, n: i32) -> f16 {
1888        intrinsics::powif16(self, n)
1889    }
1890
1891    /// Returns the square root of a number.
1892    ///
1893    /// Returns NaN if `self` is a negative number other than `-0.0`.
1894    ///
1895    /// # Precision
1896    ///
1897    /// The result of this operation is guaranteed to be the rounded
1898    /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
1899    /// and guaranteed not to change.
1900    ///
1901    /// # Examples
1902    ///
1903    /// ```
1904    /// #![feature(f16)]
1905    /// # #[cfg(not(miri))]
1906    /// # #[cfg(target_has_reliable_f16)] {
1907    ///
1908    /// let positive = 4.0_f16;
1909    /// let negative = -4.0_f16;
1910    /// let negative_zero = -0.0_f16;
1911    ///
1912    /// assert_eq!(positive.sqrt(), 2.0);
1913    /// assert!(negative.sqrt().is_nan());
1914    /// assert!(negative_zero.sqrt() == negative_zero);
1915    /// # }
1916    /// ```
1917    #[inline]
1918    #[doc(alias = "squareRoot")]
1919    #[rustc_allow_incoherent_impl]
1920    #[unstable(feature = "f16", issue = "116909")]
1921    #[must_use = "method returns a new number and does not mutate the original value"]
1922    pub fn sqrt(self) -> f16 {
1923        intrinsics::sqrtf16(self)
1924    }
1925
1926    /// Returns the cube root of a number.
1927    ///
1928    /// # Unspecified precision
1929    ///
1930    /// The precision of this function is non-deterministic. This means it varies by platform,
1931    /// Rust version, and can even differ within the same execution from one invocation to the next.
1932    ///
1933    /// This function currently corresponds to the `cbrtf` from libc on Unix
1934    /// and Windows. Note that this might change in the future.
1935    ///
1936    /// # Examples
1937    ///
1938    /// ```
1939    /// #![feature(f16)]
1940    /// # #[cfg(not(miri))]
1941    /// # #[cfg(target_has_reliable_f16)] {
1942    ///
1943    /// let x = 8.0f16;
1944    ///
1945    /// // x^(1/3) - 2 == 0
1946    /// let abs_difference = (x.cbrt() - 2.0).abs();
1947    ///
1948    /// assert!(abs_difference <= f16::EPSILON);
1949    /// # }
1950    /// ```
1951    #[inline]
1952    #[rustc_allow_incoherent_impl]
1953    #[unstable(feature = "f16", issue = "116909")]
1954    #[must_use = "method returns a new number and does not mutate the original value"]
1955    pub fn cbrt(self) -> f16 {
1956        libm::cbrtf(self as f32) as f16
1957    }
1958}