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);