malachite_base/num/conversion/
mantissa_and_exponent.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::{
10    ArithmeticCheckedShl, DivisibleByPowerOf2, ModPowerOf2, ShrRound,
11};
12use crate::num::basic::floats::PrimitiveFloat;
13use crate::num::basic::integers::PrimitiveInt;
14use crate::num::basic::unsigneds::PrimitiveUnsigned;
15use crate::num::conversion::traits::{
16    ExactFrom, IntegerMantissaAndExponent, RawMantissaAndExponent, SciMantissaAndExponent,
17    WrappingFrom,
18};
19use crate::num::logic::traits::{BitAccess, LeadingZeros, LowMask, SignificantBits, TrailingZeros};
20use crate::rounding_modes::RoundingMode::{self, *};
21use core::cmp::Ordering::{self, *};
22
23fn raw_mantissa_and_exponent<T: PrimitiveFloat>(x: T) -> (u64, u64) {
24    let bits = x.to_bits();
25    (
26        bits.mod_power_of_2(T::MANTISSA_WIDTH),
27        (bits >> T::MANTISSA_WIDTH).mod_power_of_2(T::EXPONENT_WIDTH),
28    )
29}
30
31#[inline]
32fn raw_mantissa<T: PrimitiveFloat>(x: T) -> u64 {
33    x.to_bits().mod_power_of_2(T::MANTISSA_WIDTH)
34}
35
36#[inline]
37fn raw_exponent<T: PrimitiveFloat>(x: T) -> u64 {
38    (x.to_bits() >> T::MANTISSA_WIDTH).mod_power_of_2(T::EXPONENT_WIDTH)
39}
40
41fn from_raw_mantissa_and_exponent<T: PrimitiveFloat>(raw_mantissa: u64, raw_exponent: u64) -> T {
42    assert!(raw_mantissa.significant_bits() <= T::MANTISSA_WIDTH);
43    assert!(raw_exponent.significant_bits() <= T::EXPONENT_WIDTH);
44    let x = T::from_bits((raw_exponent << T::MANTISSA_WIDTH) | raw_mantissa);
45    // Only output the canonical NaN
46    if x.is_nan() { T::NAN } else { x }
47}
48
49fn integer_mantissa_and_exponent_primitive_float<T: PrimitiveFloat>(x: T) -> (u64, i64) {
50    assert!(x.is_finite());
51    assert!(x != T::ZERO);
52    let (mut raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
53    if raw_exponent == 0 {
54        let trailing_zeros = raw_mantissa.trailing_zeros();
55        (
56            raw_mantissa >> trailing_zeros,
57            i64::wrapping_from(trailing_zeros) + T::MIN_EXPONENT,
58        )
59    } else {
60        raw_mantissa.set_bit(T::MANTISSA_WIDTH);
61        let trailing_zeros = TrailingZeros::trailing_zeros(raw_mantissa);
62        (
63            raw_mantissa >> trailing_zeros,
64            i64::wrapping_from(raw_exponent + trailing_zeros) + T::MIN_EXPONENT - 1,
65        )
66    }
67}
68
69fn integer_mantissa_primitive_float<T: PrimitiveFloat>(x: T) -> u64 {
70    assert!(x.is_finite());
71    assert!(x != T::ZERO);
72    let (mut raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
73    if raw_exponent != 0 {
74        raw_mantissa.set_bit(T::MANTISSA_WIDTH);
75    }
76    raw_mantissa >> raw_mantissa.trailing_zeros()
77}
78
79fn integer_exponent_primitive_float<T: PrimitiveFloat>(x: T) -> i64 {
80    assert!(x.is_finite());
81    assert!(x != T::ZERO);
82    let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
83    if raw_exponent == 0 {
84        i64::wrapping_from(raw_mantissa.trailing_zeros()) + T::MIN_EXPONENT
85    } else {
86        i64::wrapping_from(
87            raw_exponent
88                + if raw_mantissa == 0 {
89                    T::MANTISSA_WIDTH
90                } else {
91                    TrailingZeros::trailing_zeros(raw_mantissa)
92                },
93        ) + T::MIN_EXPONENT
94            - 1
95    }
96}
97
98fn from_integer_mantissa_and_exponent_primitive_float<T: PrimitiveFloat>(
99    integer_mantissa: u64,
100    integer_exponent: i64,
101) -> Option<T> {
102    if integer_mantissa == 0 {
103        return Some(T::ZERO);
104    }
105    let trailing_zeros = integer_mantissa.trailing_zeros();
106    let (integer_mantissa, adjusted_exponent) = (
107        integer_mantissa >> trailing_zeros,
108        integer_exponent + i64::wrapping_from(trailing_zeros),
109    );
110    let mantissa_bits = integer_mantissa.significant_bits();
111    let sci_exponent = adjusted_exponent.checked_add(i64::exact_from(mantissa_bits))? - 1;
112    let mut raw_mantissa;
113    let raw_exponent;
114    if sci_exponent < T::MIN_EXPONENT || sci_exponent > T::MAX_EXPONENT {
115        return None;
116    } else if sci_exponent < T::MIN_NORMAL_EXPONENT {
117        if adjusted_exponent < T::MIN_EXPONENT {
118            return None;
119        }
120        raw_exponent = 0;
121        raw_mantissa = integer_mantissa << (adjusted_exponent - T::MIN_EXPONENT);
122    } else if mantissa_bits > T::MANTISSA_WIDTH + 1 {
123        return None;
124    } else {
125        raw_exponent = u64::exact_from(sci_exponent + i64::low_mask(T::EXPONENT_WIDTH - 1));
126        raw_mantissa = integer_mantissa << (T::MANTISSA_WIDTH + 1 - mantissa_bits);
127        raw_mantissa.clear_bit(T::MANTISSA_WIDTH);
128    }
129    Some(T::from_raw_mantissa_and_exponent(
130        raw_mantissa,
131        raw_exponent,
132    ))
133}
134
135fn sci_mantissa_and_exponent_primitive_float<T: PrimitiveFloat>(x: T) -> (T, i64) {
136    assert!(x.is_finite());
137    assert!(x != T::ZERO);
138    let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
139    // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0.
140    if raw_exponent == 0 {
141        let leading_zeros =
142            LeadingZeros::leading_zeros(raw_mantissa) - (u64::WIDTH - T::MANTISSA_WIDTH);
143        let mut mantissa = raw_mantissa << (leading_zeros + 1);
144        mantissa.clear_bit(T::MANTISSA_WIDTH);
145        (
146            T::from_raw_mantissa_and_exponent(mantissa, u64::wrapping_from(T::MAX_EXPONENT)),
147            i64::wrapping_from(T::MANTISSA_WIDTH - leading_zeros - 1) + T::MIN_EXPONENT,
148        )
149    } else {
150        (
151            T::from_raw_mantissa_and_exponent(raw_mantissa, u64::wrapping_from(T::MAX_EXPONENT)),
152            i64::wrapping_from(raw_exponent) - T::MAX_EXPONENT,
153        )
154    }
155}
156
157fn sci_mantissa_primitive_float<T: PrimitiveFloat>(x: T) -> T {
158    assert!(x.is_finite());
159    assert!(x != T::ZERO);
160    let (mut mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
161    // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0.
162    if raw_exponent == 0 {
163        mantissa <<= LeadingZeros::leading_zeros(mantissa) - (u64::WIDTH - T::MANTISSA_WIDTH) + 1;
164        mantissa.clear_bit(T::MANTISSA_WIDTH);
165    }
166    T::from_raw_mantissa_and_exponent(mantissa, u64::wrapping_from(T::MAX_EXPONENT))
167}
168
169fn sci_exponent_primitive_float<T: PrimitiveFloat>(x: T) -> i64 {
170    assert!(x.is_finite());
171    assert!(x != T::ZERO);
172    let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent();
173    // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0.
174    if raw_exponent == 0 {
175        i64::wrapping_from(u64::WIDTH - LeadingZeros::leading_zeros(raw_mantissa) - 1)
176            + T::MIN_EXPONENT
177    } else {
178        i64::wrapping_from(raw_exponent) - T::MAX_EXPONENT
179    }
180}
181
182#[allow(clippy::wrong_self_convention)]
183fn from_sci_mantissa_and_exponent_primitive_float<T: PrimitiveFloat>(
184    sci_mantissa: T,
185    sci_exponent: i64,
186) -> Option<T> {
187    assert!(sci_mantissa.is_finite());
188    assert!(sci_mantissa > T::ZERO);
189    if sci_exponent < T::MIN_EXPONENT || sci_exponent > T::MAX_EXPONENT {
190        return None;
191    }
192    let (mut orig_mantissa, orig_exponent) = sci_mantissa.raw_mantissa_and_exponent();
193    // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0.
194    if orig_exponent != u64::wrapping_from(T::MAX_EXPONENT) {
195        return None;
196    }
197    if sci_exponent < T::MIN_NORMAL_EXPONENT {
198        let shift = T::MIN_NORMAL_EXPONENT - sci_exponent;
199        if orig_mantissa.divisible_by_power_of_2(u64::wrapping_from(shift)) {
200            orig_mantissa.set_bit(T::MANTISSA_WIDTH);
201            Some(T::from_raw_mantissa_and_exponent(orig_mantissa >> shift, 0))
202        } else {
203            None
204        }
205    } else {
206        Some(T::from_raw_mantissa_and_exponent(
207            orig_mantissa,
208            u64::wrapping_from(sci_exponent + T::MAX_EXPONENT),
209        ))
210    }
211}
212
213/// Returns the scientific mantissa and exponent of an unsinged value. An [`Ordering`] is also
214/// returned, indicating whether the mantissa and exponent correspond to a value less than, equal
215/// to, or greater than the original value.
216///
217/// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a
218/// rational number with $1 \leq m_s < 2$. We represent the rational mantissa as a float. The
219/// conversion might not be exact, so we round to the nearest float using the provided rounding
220/// mode. If the rounding mode is `Exact` but the conversion is not exact, `None` is returned.
221/// $$
222/// f(x, r) \approx (\frac{x}{2^{\lfloor \log_2 x \rfloor}}, \lfloor \log_2 x \rfloor).
223/// $$
224///
225/// # Worst-case complexity
226/// Constant time and additional memory.
227///
228/// # Examples
229/// ```
230/// use malachite_base::num::basic::floats::PrimitiveFloat;
231/// use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
232/// use malachite_base::num::conversion::mantissa_and_exponent::*;
233/// use malachite_base::num::float::NiceFloat;
234/// use malachite_base::rounding_modes::RoundingMode::{self, *};
235/// use std::cmp::Ordering::{self, *};
236///
237/// fn test<T: PrimitiveUnsigned, U: PrimitiveFloat>(
238///     n: T,
239///     rm: RoundingMode,
240///     out: Option<(U, u64, Ordering)>,
241/// ) {
242///     assert_eq!(
243///         sci_mantissa_and_exponent_round(n, rm).map(|(m, e, o)| (NiceFloat(m), e, o)),
244///         out.map(|(m, e, o)| (NiceFloat(m), e, o))
245///     );
246/// }
247/// test::<u32, f32>(3, Down, Some((1.5, 1, Equal)));
248/// test::<u32, f32>(3, Ceiling, Some((1.5, 1, Equal)));
249/// test::<u32, f32>(3, Up, Some((1.5, 1, Equal)));
250/// test::<u32, f32>(3, Nearest, Some((1.5, 1, Equal)));
251/// test::<u32, f32>(3, Exact, Some((1.5, 1, Equal)));
252///
253/// test::<u32, f32>(123, Floor, Some((1.921875, 6, Equal)));
254/// test::<u32, f32>(123, Down, Some((1.921875, 6, Equal)));
255/// test::<u32, f32>(123, Ceiling, Some((1.921875, 6, Equal)));
256/// test::<u32, f32>(123, Up, Some((1.921875, 6, Equal)));
257/// test::<u32, f32>(123, Nearest, Some((1.921875, 6, Equal)));
258/// test::<u32, f32>(123, Exact, Some((1.921875, 6, Equal)));
259///
260/// test::<u32, f32>(1000000000, Nearest, Some((1.8626451, 29, Equal)));
261/// test::<u32, f32>(999999999, Nearest, Some((1.8626451, 29, Greater)));
262/// ```
263pub fn sci_mantissa_and_exponent_round<T: PrimitiveUnsigned, U: PrimitiveFloat>(
264    x: T,
265    rm: RoundingMode,
266) -> Option<(U, u64, Ordering)> {
267    assert_ne!(x, T::ZERO);
268    let significant_bits = x.significant_bits();
269    let mut exponent = significant_bits - 1;
270    let (mut raw_mantissa, o) = if significant_bits > U::MANTISSA_WIDTH {
271        let shift = significant_bits - U::MANTISSA_WIDTH - 1;
272        if rm == Exact && TrailingZeros::trailing_zeros(x) < shift {
273            return None;
274        }
275        let (s, o) = x.shr_round(shift, rm);
276        (s.wrapping_into(), o)
277    } else {
278        let x: u64 = x.wrapping_into();
279        (x << (U::MANTISSA_WIDTH - significant_bits + 1), Equal)
280    };
281    if raw_mantissa.significant_bits() == U::MANTISSA_WIDTH + 2 {
282        // Rounding up to a power of 2
283        raw_mantissa >>= 1;
284        exponent += 1;
285    }
286    raw_mantissa.clear_bit(U::MANTISSA_WIDTH);
287    // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0.
288    Some((
289        U::from_raw_mantissa_and_exponent(raw_mantissa, u64::wrapping_from(U::MAX_EXPONENT)),
290        exponent,
291        o,
292    ))
293}
294
295/// Constructs a primitive integer from its scientific mantissa and exponent. An [`Ordering`] is
296/// also returned, indicating whether the returned value is less than, equal to, or greater than the
297/// exact value implied by the input.
298///
299/// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a
300/// rational number with $1 \leq m_s < 2$. Here, the rational mantissa is provided as a float. If
301/// the mantissa is outside the range $[1, 2)$, `None` is returned.
302///
303/// Some combinations of mantissas and exponents do not specify an integer, in which case the
304/// resulting value is rounded to an integer using the specified rounding mode. If the rounding mode
305/// is `Exact` but the input does not exactly specify an integer, `None` is returned.
306///
307/// $$
308/// f(x, r) \approx 2^{e_s}m_s.
309/// $$
310///
311/// # Worst-case complexity
312/// Constant time and additional memory.
313///
314/// # Panics
315/// Panics if `sci_mantissa` is zero.
316///
317/// # Examples
318/// ```
319/// use malachite_base::num::basic::floats::PrimitiveFloat;
320/// use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
321/// use malachite_base::num::conversion::mantissa_and_exponent::*;
322/// use malachite_base::rounding_modes::RoundingMode::{self, *};
323/// use std::cmp::Ordering::{self, *};
324///
325/// fn test<T: PrimitiveUnsigned, U: PrimitiveFloat>(
326///     mantissa: U,
327///     exponent: u64,
328///     rm: RoundingMode,
329///     out: Option<(T, Ordering)>,
330/// ) {
331///     assert_eq!(
332///         from_sci_mantissa_and_exponent_round::<T, U>(mantissa, exponent, rm),
333///         out
334///     );
335/// }
336/// test::<u32, f32>(1.5, 1, Floor, Some((3, Equal)));
337/// test::<u32, f32>(1.5, 1, Down, Some((3, Equal)));
338/// test::<u32, f32>(1.5, 1, Ceiling, Some((3, Equal)));
339/// test::<u32, f32>(1.5, 1, Up, Some((3, Equal)));
340/// test::<u32, f32>(1.5, 1, Nearest, Some((3, Equal)));
341/// test::<u32, f32>(1.5, 1, Exact, Some((3, Equal)));
342///
343/// test::<u32, f32>(1.51, 1, Floor, Some((3, Less)));
344/// test::<u32, f32>(1.51, 1, Down, Some((3, Less)));
345/// test::<u32, f32>(1.51, 1, Ceiling, Some((4, Greater)));
346/// test::<u32, f32>(1.51, 1, Up, Some((4, Greater)));
347/// test::<u32, f32>(1.51, 1, Nearest, Some((3, Less)));
348/// test::<u32, f32>(1.51, 1, Exact, None);
349///
350/// test::<u32, f32>(2.0, 1, Floor, None);
351/// test::<u32, f32>(10.0, 1, Floor, None);
352/// test::<u32, f32>(0.5, 1, Floor, None);
353/// ```
354pub fn from_sci_mantissa_and_exponent_round<T: PrimitiveUnsigned, U: PrimitiveFloat>(
355    sci_mantissa: U,
356    sci_exponent: u64,
357    rm: RoundingMode,
358) -> Option<(T, Ordering)> {
359    assert_ne!(sci_mantissa, U::ZERO);
360    if sci_mantissa < U::ONE || sci_mantissa >= U::TWO {
361        return None;
362    }
363    let mut raw_mantissa = sci_mantissa.raw_mantissa();
364    raw_mantissa.set_bit(U::MANTISSA_WIDTH);
365    if sci_exponent >= U::MANTISSA_WIDTH {
366        T::try_from(raw_mantissa)
367            .ok()?
368            .arithmetic_checked_shl(sci_exponent - U::MANTISSA_WIDTH)
369            .map(|n| (n, Equal))
370    } else {
371        let shift = U::MANTISSA_WIDTH - sci_exponent;
372        if rm == Exact && TrailingZeros::trailing_zeros(raw_mantissa) < shift {
373            return None;
374        }
375        let (s, o) = raw_mantissa.shr_round(shift, rm);
376        T::try_from(s).ok().map(|s| (s, o))
377    }
378}
379
380macro_rules! impl_mantissa_and_exponent_unsigned {
381    ($t:ident) => {
382        impl IntegerMantissaAndExponent<$t, u64> for $t {
383            /// Returns the integer mantissa and exponent.
384            ///
385            /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and
386            /// $m_i$ is an odd integer.
387            /// $$
388            /// f(x) = (\frac{|x|}{2^{e_i}}, e_i),
389            /// $$
390            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
391            ///
392            /// The inverse operation is
393            /// [`from_integer_mantissa_and_exponent`](Self::from_integer_mantissa_and_exponent).
394            ///
395            /// # Worst-case complexity
396            /// Constant time and additional memory.
397            ///
398            /// # Panics
399            /// Panics if `self` is zero.
400            ///
401            /// # Examples
402            /// See [here](super::mantissa_and_exponent#integer_mantissa_and_exponent).
403            #[inline]
404            fn integer_mantissa_and_exponent(self) -> ($t, u64) {
405                assert_ne!(self, 0);
406                let exponent = TrailingZeros::trailing_zeros(self);
407                (self >> exponent, exponent)
408            }
409
410            /// Returns the integer mantissa.
411            ///
412            /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and
413            /// $m_i$ is an odd integer.
414            /// $$
415            /// f(x) = \frac{|x|}{2^{e_i}},
416            /// $$
417            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
418            ///
419            /// # Worst-case complexity
420            /// Constant time and additional memory.
421            ///
422            /// # Panics
423            /// Panics if `self` is zero.
424            ///
425            /// # Examples
426            /// See [here](super::mantissa_and_exponent#integer_mantissa).
427            #[inline]
428            fn integer_mantissa(self) -> $t {
429                assert_ne!(self, 0);
430                self >> self.trailing_zeros()
431            }
432
433            /// Returns the integer exponent.
434            ///
435            /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and
436            /// $m_i$ is an odd integer.
437            /// $$
438            /// f(x) = e_i,
439            /// $$
440            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
441            ///
442            /// # Worst-case complexity
443            /// Constant time and additional memory.
444            ///
445            /// # Panics
446            /// Panics if `self` is zero.
447            ///
448            /// # Examples
449            /// See [here](super::mantissa_and_exponent#integer_exponent).
450            #[inline]
451            fn integer_exponent(self) -> u64 {
452                assert_ne!(self, 0);
453                TrailingZeros::trailing_zeros(self)
454            }
455
456            /// Constructs an unsigned primitive integer from its integer mantissa and exponent.
457            ///
458            /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and
459            /// $m_i$ is an odd integer.
460            ///
461            /// $$
462            /// f(x) = 2^{e_i}m_i,
463            /// $$
464            /// or `None` if the result cannot be exactly represented as an integer of the desired
465            /// type (this happens if the exponent is too large).
466            ///
467            /// The input does not have to be reduced; that is to say, the mantissa does not have to
468            /// be odd.
469            ///
470            /// # Worst-case complexity
471            /// Constant time and additional memory.
472            ///
473            /// # Examples
474            /// See [here](super::mantissa_and_exponent#from_integer_mantissa_and_exponent).
475            #[inline]
476            fn from_integer_mantissa_and_exponent(
477                integer_mantissa: $t,
478                integer_exponent: u64,
479            ) -> Option<$t> {
480                integer_mantissa.arithmetic_checked_shl(integer_exponent)
481            }
482        }
483    };
484}
485apply_to_unsigneds!(impl_mantissa_and_exponent_unsigned);
486
487macro_rules! impl_sci_mantissa_and_exponent_unsigned {
488    ($u:ident) => {
489        macro_rules! impl_sci_mantissa_and_exponent_unsigned_inner {
490            ($f:ident) => {
491                impl SciMantissaAndExponent<$f, u64> for $u {
492                    /// Returns the scientific mantissa and exponent.
493                    ///
494                    /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an
495                    /// integer and $m_s$ is a rational number with $1 \leq m_s < 2$. We represent
496                    /// the rational mantissa as a float. The conversion might not be exact, so we
497                    /// round to the nearest float using the `Nearest` rounding mode. To use other
498                    /// rounding modes, use [`sci_mantissa_and_exponent_round`].
499                    ///
500                    /// If the result cannot be expressed as an integer of the specified type,
501                    /// `None` is returned.
502                    /// $$
503                    /// f(x) \approx (\frac{x}{2^{\lfloor \log_2 x \rfloor}},
504                    /// \lfloor \log_2 x \rfloor).
505                    /// $$
506                    ///
507                    /// # Worst-case complexity
508                    /// Constant time and additional memory.
509                    ///
510                    /// # Panics
511                    /// Panics if `self` is zero.
512                    ///
513                    /// # Examples
514                    /// See [here](super::mantissa_and_exponent#sci_mantissa_and_exponent).
515                    #[inline]
516                    fn sci_mantissa_and_exponent(self) -> ($f, u64) {
517                        let (m, e, _) = sci_mantissa_and_exponent_round(self, Nearest).unwrap();
518                        (m, e)
519                    }
520
521                    /// Constructs a primitive integer from its scientific mantissa and exponent.
522                    ///
523                    /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an
524                    /// integer and $m_s$ is a rational number with $1 \leq m_s < 2$. Here, the
525                    /// rational mantissa is provided as a float. If the mantissa is outside the
526                    /// range $[1, 2)$, `None` is returned.
527                    ///
528                    /// Some combinations of mantissas and exponents do not specify an integer, in
529                    /// which case the resulting value is rounded to an integer using the `Nearest`
530                    /// rounding mode. To specify other rounding modes, use
531                    /// [`from_sci_mantissa_and_exponent_round`].
532                    ///
533                    /// $$
534                    /// f(x) \approx 2^{e_s}m_s.
535                    /// $$
536                    ///
537                    /// # Worst-case complexity
538                    /// Constant time and additional memory.
539                    ///
540                    /// # Panics
541                    /// Panics if `sci_mantissa` is zero.
542                    ///
543                    /// # Examples
544                    /// See [here](super::mantissa_and_exponent#from_sci_mantissa_and_exponent).
545                    #[inline]
546                    fn from_sci_mantissa_and_exponent(
547                        sci_mantissa: $f,
548                        sci_exponent: u64,
549                    ) -> Option<$u> {
550                        from_sci_mantissa_and_exponent_round(sci_mantissa, sci_exponent, Nearest)
551                            .map(|p| p.0)
552                    }
553                }
554            };
555        }
556        apply_to_primitive_floats!(impl_sci_mantissa_and_exponent_unsigned_inner);
557    };
558}
559apply_to_unsigneds!(impl_sci_mantissa_and_exponent_unsigned);
560
561macro_rules! impl_mantissa_and_exponent_primitive_float {
562    ($t:ident) => {
563        impl RawMantissaAndExponent<u64, u64> for $t {
564            /// Returns the raw mantissa and exponent.
565            ///
566            /// The raw exponent and raw mantissa are the actual bit patterns used to represent the
567            /// components of `self`. When `self` is nonzero and finite, the raw exponent $e_r$ is
568            /// an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an integer in $[0, 2^M-1]$.
569            ///
570            /// When `self` is nonzero and finite, $f(x) = (m_r, e_r)$, where
571            /// $$
572            /// m_r = \\begin{cases}
573            ///     2^{M+2^{E-1}-2}|x| & \text{if} \\quad |x| < 2^{2-2^{E-1},} \\\\
574            ///     2^M \left ( \frac{|x|}{2^{\lfloor \log_2 |x| \rfloor}}-1\right ) &
575            ///     \textrm{otherwise},
576            /// \\end{cases}
577            /// $$
578            /// and
579            /// $$
580            /// e_r = \\begin{cases}
581            ///     0 & \text{if} \\quad |x| < 2^{2-2^{E-1}} \\\\
582            ///     \lfloor \log_2 |x| \rfloor + 2^{E-1} - 1 & \textrm{otherwise}.
583            /// \\end{cases}
584            /// $$
585            /// and $M$ and $E$ are the mantissa width and exponent width, respectively.
586            ///
587            /// For zeros, infinities, or `NaN`, refer to [IEEE
588            /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below.
589            ///
590            /// The inverse operation is [`Self::from_raw_mantissa_and_exponent`].
591            ///
592            /// # Worst-case complexity
593            /// Constant time and additional memory.
594            ///
595            /// # Examples
596            /// See [here](super::mantissa_and_exponent#raw_mantissa_and_exponent).
597            #[inline]
598            fn raw_mantissa_and_exponent(self) -> (u64, u64) {
599                raw_mantissa_and_exponent(self)
600            }
601
602            /// Returns the raw mantissa.
603            ///
604            /// The raw mantissa is the actual bit pattern used to represent the mantissa of `self`.
605            /// When `self` is nonzero and finite, it is an integer in $[0, 2^M-1]$.
606            ///
607            /// When `self` is nonzero and finite,
608            /// $$
609            /// f(x) = \\begin{cases}
610            ///     2^{M+2^{E-1}-2}|x| & \text{if} \\quad |x| < 2^{2-2^{E-1}}, \\\\
611            ///     2^M \left ( \frac{|x|}{2^{\lfloor \log_2 |x| \rfloor}}-1\right )
612            ///     & \textrm{otherwise},
613            /// \\end{cases}
614            /// $$
615            /// where $M$ and $E$ are the mantissa width and exponent width, respectively.
616            ///
617            /// For zeros, infinities, or `NaN`, refer to [IEEE
618            /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below.
619            ///
620            /// # Worst-case complexity
621            /// Constant time and additional memory.
622            ///
623            /// # Examples
624            /// See [here](super::mantissa_and_exponent#raw_mantissa).
625            #[inline]
626            fn raw_mantissa(self) -> u64 {
627                raw_mantissa(self)
628            }
629
630            /// Returns the raw exponent.
631            ///
632            /// The raw exponent is the actual bit pattern used to represent the exponent of `self`.
633            /// When `self` is nonzero and finite, it is an integer in $[0, 2^E-2]$.
634            ///
635            /// When `self` is nonzero and finite,
636            /// $$
637            /// f(x) = \\begin{cases}
638            ///     0 & \text{if} \\quad |x| < 2^{2-2^{E-1}}, \\\\
639            ///     \lfloor \log_2 |x| \rfloor + 2^{E-1} - 1 & \textrm{otherwise},
640            /// \\end{cases}
641            /// $$
642            /// where $M$ and $E$ are the mantissa width and exponent width, respectively.
643            ///
644            /// For zeros, infinities, or `NaN`, refer to [IEEE
645            /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below.
646            ///
647            /// # Worst-case complexity
648            /// Constant time and additional memory.
649            ///
650            /// # Examples
651            /// See [here](super::mantissa_and_exponent#raw_exponent).
652            #[inline]
653            fn raw_exponent(self) -> u64 {
654                raw_exponent(self)
655            }
656
657            /// Constructs a float from its raw mantissa and exponent.
658            ///
659            /// The raw exponent and raw mantissa are the actual bit patterns used to represent the
660            /// components of a float. When the float is nonzero and finite, the raw exponent $e_r$
661            /// is an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an integer in $[0,
662            /// 2^M-1]$.
663            ///
664            /// When the exponent is not `2^E-1`,
665            /// $$
666            /// f(m_r, e_r) = \\begin{cases}
667            ///     2^{2-2^{E-1}-M}m_r & \text{if} \\quad e_r = 0, \\\\
668            ///     2^{e_r-2^{E-1}+1}(2^{-M}m_r+1) & \textrm{otherwise},
669            /// \\end{cases}
670            /// $$
671            /// where $M$ and $E$ are the mantissa width and exponent width, respectively.
672            ///
673            /// For zeros, infinities, or `NaN`, refer to [IEEE
674            /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below.
675            ///
676            /// This function only outputs a single, canonical, `NaN`.
677            ///
678            /// # Worst-case complexity
679            /// Constant time and additional memory.
680            ///
681            /// # Examples
682            /// See [here](super::mantissa_and_exponent#from_raw_mantissa_and_exponent).
683            #[inline]
684            fn from_raw_mantissa_and_exponent(raw_mantissa: u64, raw_exponent: u64) -> $t {
685                from_raw_mantissa_and_exponent(raw_mantissa, raw_exponent)
686            }
687        }
688
689        impl IntegerMantissaAndExponent<u64, i64> for $t {
690            /// Returns the integer mantissa and exponent.
691            ///
692            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where
693            /// $e_i$ is an integer and $m_i$ is an odd integer.
694            /// $$
695            /// f(x) = (\frac{|x|}{2^{e_i}}, e_i),
696            /// $$
697            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
698            ///
699            /// The inverse operation is [`Self::from_integer_mantissa_and_exponent`].
700            ///
701            /// # Worst-case complexity
702            /// Constant time and additional memory.
703            ///
704            /// # Panics
705            /// Panics if `self` is zero, infinite, or `NaN`.
706            ///
707            /// # Examples
708            /// See [here](super::mantissa_and_exponent#integer_mantissa_and_exponent).
709            #[inline]
710            fn integer_mantissa_and_exponent(self) -> (u64, i64) {
711                integer_mantissa_and_exponent_primitive_float(self)
712            }
713
714            /// Returns the integer mantissa.
715            ///
716            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where
717            /// $e_i$ is an integer and $m_i$ is an odd integer.
718            /// $$
719            /// f(x) = \frac{|x|}{2^{e_i}},
720            /// $$
721            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
722            ///
723            /// # Worst-case complexity
724            /// Constant time and additional memory.
725            ///
726            /// # Panics
727            /// Panics if `self` is zero, infinite, or `NaN`.
728            ///
729            /// # Examples
730            /// See [here](super::mantissa_and_exponent#integer_mantissa).
731            #[inline]
732            fn integer_mantissa(self) -> u64 {
733                integer_mantissa_primitive_float(self)
734            }
735
736            /// Returns the integer exponent.
737            ///
738            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where
739            /// $e_i$ is an integer and $m_i$ is an odd integer.
740            /// $$
741            /// f(x) = e_i,
742            /// $$
743            /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer.
744            ///
745            /// # Worst-case complexity
746            /// Constant time and additional memory.
747            ///
748            /// # Panics
749            /// Panics if `self` is zero, infinite, or `NaN`.
750            ///
751            /// # Examples
752            /// See [here](super::mantissa_and_exponent#integer_exponent).
753            #[inline]
754            fn integer_exponent(self) -> i64 {
755                integer_exponent_primitive_float(self)
756            }
757
758            /// Constructs a float from its integer mantissa and exponent.
759            ///
760            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where
761            /// $e_i$ is an integer and $m_i$ is an odd integer.
762            ///
763            /// $$
764            /// f(x) = 2^{e_i}m_i,
765            /// $$
766            /// or `None` if the result cannot be exactly represented as a float of the desired type
767            /// (this happens if the exponent is too large or too small, or if the mantissa's
768            /// precision is too high for the exponent).
769            ///
770            /// The input does not have to be reduced; that is to say, the mantissa does not have to
771            /// be odd.
772            ///
773            /// # Worst-case complexity
774            /// Constant time and additional memory.
775            ///
776            /// # Examples
777            /// See [here](super::mantissa_and_exponent#from_integer_mantissa_and_exponent).
778            #[inline]
779            fn from_integer_mantissa_and_exponent(
780                integer_mantissa: u64,
781                integer_exponent: i64,
782            ) -> Option<$t> {
783                from_integer_mantissa_and_exponent_primitive_float(
784                    integer_mantissa,
785                    integer_exponent,
786                )
787            }
788        }
789
790        impl SciMantissaAndExponent<$t, i64> for $t {
791            /// Returns the scientific mantissa and exponent.
792            ///
793            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where
794            /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. If $x$ is
795            /// a valid float, the scientific mantissa $m_s$ is always exactly representable as a
796            /// float of the same type. We have
797            /// $$
798            /// f(x) = (\frac{x}{2^{\lfloor \log_2 x \rfloor}}, \lfloor \log_2 x \rfloor).
799            /// $$
800            ///
801            /// The inverse operation is `from_sci_mantissa_and_exponent`.
802            ///
803            /// # Worst-case complexity
804            /// Constant time and additional memory.
805            ///
806            /// # Panics
807            /// Panics if `self` is zero, infinite, or `NaN`.
808            ///
809            /// # Examples
810            /// See [here](super::mantissa_and_exponent#sci_mantissa_and_exponent).
811            #[inline]
812            fn sci_mantissa_and_exponent(self) -> ($t, i64) {
813                sci_mantissa_and_exponent_primitive_float(self)
814            }
815
816            /// Returns the scientific mantissa.
817            ///
818            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where
819            /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. If $x$ is
820            /// a valid float, the scientific mantissa $m_s$ is always exactly representable as a
821            /// float of the same type. We have
822            /// $$
823            /// f(x) = \frac{x}{2^{\lfloor \log_2 x \rfloor}}.
824            /// $$
825            ///
826            /// # Worst-case complexity
827            /// Constant time and additional memory.
828            ///
829            /// # Panics
830            /// Panics if `self` is zero, infinite, or `NaN`.
831            ///
832            /// # Examples
833            /// See [here](super::mantissa_and_exponent#sci_mantissa).
834            #[inline]
835            fn sci_mantissa(self) -> $t {
836                sci_mantissa_primitive_float(self)
837            }
838
839            /// Returns the scientific exponent.
840            ///
841            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where
842            /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. We have
843            /// $$
844            /// f(x) = \lfloor \log_2 x \rfloor.
845            /// $$
846            ///
847            /// # Worst-case complexity
848            /// Constant time and additional memory.
849            ///
850            /// # Panics
851            /// Panics if `self` is zero, infinite, or `NaN`.
852            ///
853            /// # Examples
854            /// See [here](super::mantissa_and_exponent#sci_exponent).
855            #[inline]
856            fn sci_exponent(self) -> i64 {
857                sci_exponent_primitive_float(self)
858            }
859
860            /// Constructs a float from its scientific mantissa and exponent.
861            ///
862            /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where
863            /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$.
864            ///
865            /// $$
866            /// f(x) = 2^{e_s}m_s,
867            /// $$
868            /// or `None` if the result cannot be exactly represented as a float of the desired type
869            /// (this happens if the exponent is too large or too small, if the mantissa is not in
870            /// the range $[1, 2)$, or if the mantissa's precision is too high for the exponent).
871            ///
872            /// # Worst-case complexity
873            /// Constant time and additional memory.
874            ///
875            /// # Panics
876            /// Panics if `mantissa` is zero, infinite, or `NaN`.
877            ///
878            /// # Examples
879            /// See [here](super::mantissa_and_exponent#from_sci_mantissa_and_exponent).
880            #[inline]
881            fn from_sci_mantissa_and_exponent(sci_mantissa: $t, sci_exponent: i64) -> Option<$t> {
882                from_sci_mantissa_and_exponent_primitive_float(sci_mantissa, sci_exponent)
883            }
884        }
885    };
886}
887apply_to_primitive_floats!(impl_mantissa_and_exponent_primitive_float);