Skip to main content

malachite_float/float/arithmetic/
power_of_2_of_float.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5//      Copyright 2001-2025 Free Software Foundation, Inc.
6//
7//      Contributed by the Pascaline and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
16use crate::float::arithmetic::exp::{
17    exp_overflow, exp_rational_near_one, exp_underflow, one_neighbor,
18};
19use crate::float::arithmetic::round_near_x::float_round_near_x;
20use crate::{Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, floor_and_ceiling};
21use core::cmp::Ordering::{self, *};
22use malachite_base::num::arithmetic::traits::{CeilingLogBase2, PowerOf2, PowerOf2Assign, Sign};
23use malachite_base::num::basic::floats::PrimitiveFloat;
24use malachite_base::num::basic::integers::PrimitiveInt;
25use malachite_base::num::basic::traits::{
26    Infinity as InfinityTrait, NaN as NaNTrait, One, Zero as ZeroTrait,
27};
28use malachite_base::num::conversion::traits::{ExactFrom, IsInteger, RoundingFrom};
29use malachite_base::num::logic::traits::SignificantBits;
30use malachite_base::rounding_modes::RoundingMode::{self, *};
31use malachite_nz::integer::Integer;
32use malachite_nz::natural::arithmetic::float::round::float_can_round;
33use malachite_nz::platform::{Limb, SignedLimb};
34use malachite_q::Rational;
35
36fn power_of_2_of_float_prec_round_normal_helper(
37    xfrac: &Float,
38    xint: i64,
39    precy: u64,
40    rm: RoundingMode,
41) -> (Float, Ordering) {
42    // For tiny xfrac, 2^xfrac is very close to 1 (above it if xfrac > 0, below if xfrac < 0), with
43    // |2^xfrac - 1| < |xfrac| < 2^EXP(xfrac). Round it from 1 directly when possible: otherwise the
44    // `exp` below would balloon its own working precision to ~ -EXP(xfrac) (up to ~2^30) just to
45    // resolve the rounding of 1 + tiny. This is the `power_of_2_rational_near_one` fast path,
46    // applied to the `Float` case.
47    let ex = i64::from(xfrac.get_exponent().unwrap());
48    if let Some((mut y, o)) = float_round_near_x(
49        &Float::ONE,
50        u64::exact_from(1 - ex),
51        *xfrac > 0u32,
52        precy,
53        rm,
54    ) {
55        // Multiply by 2^xint. `y` is already rounded to `precy`, and `o` already compares it to the
56        // exact 2^xfrac, so the shift helper is called directly with that ternary: it adjusts the
57        // exponent, substituting the correct overflow or underflow result if the shift leaves the
58        // valid exponent range.
59        let o = y.shl_prec_round_assign_helper(xint, precy, rm, o);
60        return (y, o);
61    }
62    let mut working_prec = precy + 5 + precy.ceiling_log_base_2();
63    let mut increment = Limb::WIDTH;
64    loop {
65        let ln_2 = Float::ln_2_prec_round(working_prec, Up).0;
66        let mut t = xfrac.mul_prec_round_ref_val(ln_2, working_prec, Up).0; // xfrac * ln(2)
67        // Error estimate (cf. mpfr_exp2): the relative error of t (computed with two roundings) is
68        // bounded so that exp(t) is correct to `err` bits.
69        let err = u64::exact_from(
70            i64::exact_from(working_prec) - (i64::from(t.get_exponent().unwrap()) + 2),
71        );
72        t.exp_prec_assign(working_prec); // exp(xfrac * ln(2))
73        if float_can_round(t.significand_ref().unwrap(), err, precy, rm) {
74            // Round to `precy` and multiply by 2^xint. MPFR performs the multiplication in an
75            // extended exponent range and applies the range reduction in mpfr_check_range;
76            // `shl_prec_round` provides the same overflow and underflow handling here. In
77            // particular, when `Nearest` rounds 2^xfrac down to exactly 1/2 and xint = MIN_EXPONENT
78            // - 1, the shifted value is the midpoint between 0 and the smallest positive Float, but
79            // the rounding's ternary shows that the exact value lies above the midpoint, so the
80            // result rounds up to that smallest value rather than underflowing to zero.
81            return t.shl_prec_round(xint, precy, rm);
82        }
83        working_prec += increment;
84        increment = working_prec >> 1;
85    }
86}
87
88// This is mpfr_exp2 from exp2.c, MPFR 4.2.2, where the input is finite and nonzero and the float is
89// taken by reference.
90fn power_of_2_of_float_prec_round_normal(
91    x: &Float,
92    precy: u64,
93    rm: RoundingMode,
94) -> (Float, Ordering) {
95    // 2^x overflows once x >= MAX_EXPONENT, and underflows once x <= MIN_EXPONENT - 2 (the smallest
96    // representable positive value is 2^(MIN_EXPONENT - 1)).
97    if *x >= const { Float::const_from_signed(Float::MAX_EXPONENT as SignedLimb) } {
98        return exp_overflow(precy, rm);
99    }
100    if *x <= const { Float::const_from_signed((Float::MIN_EXPONENT as SignedLimb) - 2) } {
101        return exp_underflow(precy, rm);
102    }
103    // We now know that MIN_EXPONENT - 2 < x < MAX_EXPONENT, so the integer part fits in an i64.
104    let xint = i64::exact_from(&Integer::rounding_from(x, Down).0); // trunc(x), toward zero
105    // If x is an integer, 2^x is a power of 2, hence exact.
106    if x.is_integer() {
107        return Float::power_of_2_prec_round(xint, precy, rm);
108    }
109    // 2^x for a non-integer Float is transcendental, hence never exactly representable.
110    assert_ne!(rm, Exact, "Inexact power_of_2_of_float");
111    // 2^x = 2^xint * 2^xfrac, where xfrac = x - xint and |xfrac| < 1. We compute 2^xfrac =
112    // exp(xfrac * ln(2)) and then multiply by 2^xint by shifting the result's exponent.
113    let p = x.get_prec().unwrap();
114    if xint == 0 {
115        power_of_2_of_float_prec_round_normal_helper(x, 0, precy, rm)
116    } else {
117        // x - xint is exact: the difference has fewer significant bits than x.
118        let xint_f = Float::from_integer_prec(Integer::from(xint), p).0;
119        let xfrac = x.sub_prec_round_ref_val(xint_f, p, Floor).0;
120        power_of_2_of_float_prec_round_normal_helper(&xfrac, xint, precy, rm)
121    }
122}
123
124// Computes `2 ^ x` for a nonzero `Rational` `x` with MPFR-style exponent `exp_x = floor(log2|x|) +
125// 1 <= MIN_EXPONENT`, so `|x| < 2^MIN_EXPONENT` and `x` is too small to be a normal `Float` (the
126// squeeze in `power_of_2_rational_helper` cannot bracket it). Then `2 ^ x` is extremely close to 1:
127// `0 < |2^x - 1| < |x| < 2^exp_x = 2^(EXP(1) - (1 - exp_x))`, above 1 if `x > 0` and below it if `x
128// < 0`.
129//
130// As a fast path, `float_round_near_x` rounds `2 ^ x` from 1 alone (no evaluation of `2 ^ x`)
131// whenever `prec < -exp_x`. Otherwise we compute it: `2 ^ x = exp(x * ln(2))`, so bracketing
132// `ln(2)` between two `Rational`s and applying `exp_rational_near_one` to each product brackets `2
133// ^ x`. The key point is that the needed `ln(2)` precision is only about `prec - (-exp_x)` bits,
134// not `prec`: `x` is so tiny that the bracket `x * (ln_2_hi - ln_2_lo)` shrinks far faster than the
135// result's ulp. So `ln_2_prec_round` is called at a modest precision, never near the `~2^30`
136// ceiling where it would overflow.
137fn power_of_2_rational_near_one(
138    x: &Rational,
139    exp_x: i64,
140    prec: u64,
141    rm: RoundingMode,
142) -> (Float, Ordering) {
143    let above = x.sign() == Greater;
144    let err = u64::exact_from(1 - exp_x);
145    if let Some(result) = float_round_near_x(&Float::ONE, err, above, prec, rm) {
146        return result;
147    }
148    // prec >= -exp_x. ln(2) needs roughly `prec - (-exp_x)` bits to separate the two products at
149    // the target precision; start a little above that and let the Ziv loop grow it.
150    let mut working_prec = (prec - u64::exact_from(-exp_x)) + Limb::WIDTH;
151    let mut increment = Limb::WIDTH;
152    loop {
153        // ln_2_lo <= ln(2) <= ln_2_hi, as exact Rationals, from a single ln(2) computation.
154        let (ln_2_lo, ln_2_hi) = floor_and_ceiling(Float::ln_2_prec_round(working_prec, Floor));
155        let ln_2_lo = Rational::exact_from(&ln_2_lo);
156        let ln_2_hi = Rational::exact_from(&ln_2_hi);
157        // x * ln(2) lies between x * ln_2_lo and x * ln_2_hi, and exp is increasing, so 2 ^ x lies
158        // between exp of these two products.
159        let (lo, o_lo) = exp_rational_near_one(&(x * ln_2_lo), prec, rm);
160        let (hi, o_hi) = exp_rational_near_one(&(x * ln_2_hi), prec, rm);
161        if o_lo == o_hi && lo == hi {
162            return (lo, o_lo);
163        }
164        working_prec += increment;
165        increment = working_prec >> 1;
166    }
167}
168
169// Computes `2 ^ x` for a non-integer `Rational` `x`, rounded to precision `prec` with rounding mode
170// `rm`. (Integer `x`, including 0, is handled by the caller, where `2 ^ x` is an exact power of 2.)
171// `2 ^ x` for a non-integer `x` is transcendental, hence never exactly representable, so `rm` must
172// not be `Exact`.
173fn power_of_2_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
174    assert_ne!(rm, Exact, "Inexact power_of_2");
175    let positive = x.sign() == Greater;
176    let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
177    // |x| is too large to be a finite Float, so 2^x overflows (x > 0) or underflows (x < 0).
178    // Smaller x that still overflow/underflow are caught by `power_of_2_of_float_prec_round_normal`
179    // in the loop below.
180    if exp_x >= Float::MAX_EXPONENT_I64 {
181        return if positive {
182            exp_overflow(prec, rm)
183        } else {
184            exp_underflow(prec, rm)
185        };
186    }
187    // x is too small to be represented as a normal Float (|x| < 2^MIN_EXPONENT). The squeeze below
188    // cannot bracket it, so round 2^x directly from 1 instead.
189    if exp_x <= Float::MIN_EXPONENT_I64 {
190        return power_of_2_rational_near_one(x, exp_x, prec, rm);
191    }
192    // Tiny x: if |x| < 2^(-prec) then 2^x is within half an ulp of 1, so it rounds to 1 (or, for
193    // directed rounding away from 1, to the neighbor of 1). This mirrors the tiny-x fast path of
194    // exp.
195    if -exp_x > i64::exact_from(prec) {
196        return match (positive, rm) {
197            (false, Down | Floor) => (one_neighbor(prec, false), Less), // 1 - ulp
198            (true, Up | Ceiling) => (one_neighbor(prec, true), Greater), // 1 + ulp
199            (true, _) => (Float::one_prec(prec), Less),
200            (false, _) => (Float::one_prec(prec), Greater),
201        };
202    }
203    // General case: bracket x between the Floats x_lo <= x <= x_hi, raise 2 to both, and increase
204    // the working precision until the two bounds round to the same result. 2^x is monotonic, so
205    // once the bounds agree the exact 2^x (which lies between them) rounds the same way.
206    let mut working_prec = prec + 10;
207    let mut increment = Limb::WIDTH;
208    loop {
209        let (x_lo, x_o) = Float::from_rational_prec_round_ref(x, working_prec, Floor);
210        if x_o == Equal {
211            // x (a non-integer dyadic rational) is exactly representable at `working_prec`, so 2^x
212            // is simply 2^x_lo, computed by `power_of_2_of_float_prec_round_normal`.
213            return power_of_2_of_float_prec_round_normal(&x_lo, prec, rm);
214        }
215        let (x_lo, x_hi) = floor_and_ceiling((x_lo, x_o));
216        let (e_lo, o_lo) = power_of_2_of_float_prec_round_normal(&x_lo, prec, rm);
217        let (e_hi, o_hi) = power_of_2_of_float_prec_round_normal(&x_hi, prec, rm);
218        if o_lo == o_hi && e_lo == e_hi {
219            return (e_lo, o_lo);
220        }
221        working_prec += increment;
222        increment = working_prec >> 1;
223    }
224}
225
226impl Float {
227    #[allow(clippy::needless_pass_by_value)]
228    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the specified precision and
229    /// with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also
230    /// returned, indicating whether the rounded power is less than, equal to, or greater than the
231    /// exact power. Although `NaN`s are not comparable to any [`Float`], whenever this function
232    /// returns a `NaN` it also returns `Equal`.
233    ///
234    /// See [`RoundingMode`] for a description of the possible rounding modes.
235    ///
236    /// $$
237    /// f(x,p,m) = 2^x+\varepsilon.
238    /// $$
239    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
240    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
241    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$.
242    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
243    ///   2^{\lfloor\log_2 2^x\rfloor-p}$.
244    ///
245    /// If the output has a precision, it is `prec`.
246    ///
247    /// Special cases:
248    /// - $f(\text{NaN},p,m)=\text{NaN}$
249    /// - $f(\infty,p,m)=\infty$
250    /// - $f(-\infty,p,m)=0.0$
251    /// - $f(\pm0.0,p,m)=1.0$
252    ///
253    /// Overflow and underflow:
254    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
255    ///   returned instead.
256    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
257    ///   returned instead.
258    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
259    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
260    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
261    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
262    ///   instead.
263    ///
264    /// If you know you'll be using `Nearest`, consider using [`Float::power_of_2_of_float_prec`]
265    /// instead. If you know that your target precision is the precision of the input, consider
266    /// using [`Float::power_of_2_of_float_round`] instead. If both of these things are true,
267    /// consider using the [`PowerOf2`] implementation instead.
268    ///
269    /// # Worst-case complexity
270    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
271    ///
272    /// $M(n, m) = O(n \log n + m)$
273    ///
274    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
275    /// `self.significant_bits()`.
276    ///
277    /// # Panics
278    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
279    /// with the given precision.
280    ///
281    /// # Examples
282    /// ```
283    /// use malachite_base::rounding_modes::RoundingMode::*;
284    /// use malachite_float::Float;
285    /// use std::cmp::Ordering::*;
286    ///
287    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Floor);
288    /// assert_eq!(p.to_string(), "2.75");
289    /// assert_eq!(o, Less);
290    ///
291    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Ceiling);
292    /// assert_eq!(p.to_string(), "2.88");
293    /// assert_eq!(o, Greater);
294    ///
295    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Nearest);
296    /// assert_eq!(p.to_string(), "2.88");
297    /// assert_eq!(o, Greater);
298    ///
299    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Floor);
300    /// assert_eq!(p.to_string(), "2.8284264");
301    /// assert_eq!(o, Less);
302    ///
303    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Ceiling);
304    /// assert_eq!(p.to_string(), "2.8284302");
305    /// assert_eq!(o, Greater);
306    ///
307    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Nearest);
308    /// assert_eq!(p.to_string(), "2.8284264");
309    /// assert_eq!(o, Less);
310    /// ```
311    #[inline]
312    pub fn power_of_2_of_float_prec_round(
313        pow: Self,
314        prec: u64,
315        rm: RoundingMode,
316    ) -> (Self, Ordering) {
317        Self::power_of_2_of_float_prec_round_ref(&pow, prec, rm)
318    }
319
320    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the specified precision and
321    /// with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is
322    /// also returned, indicating whether the rounded power is less than, equal to, or greater than
323    /// the exact power. Although `NaN`s are not comparable to any [`Float`], whenever this function
324    /// returns a `NaN` it also returns `Equal`.
325    ///
326    /// See [`RoundingMode`] for a description of the possible rounding modes.
327    ///
328    /// $$
329    /// f(x,p,m) = 2^x+\varepsilon.
330    /// $$
331    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
332    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
333    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$.
334    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
335    ///   2^{\lfloor\log_2 2^x\rfloor-p}$.
336    ///
337    /// If the output has a precision, it is `prec`.
338    ///
339    /// Special cases:
340    /// - $f(\text{NaN},p,m)=\text{NaN}$
341    /// - $f(\infty,p,m)=\infty$
342    /// - $f(-\infty,p,m)=0.0$
343    /// - $f(\pm0.0,p,m)=1.0$
344    ///
345    /// Overflow and underflow:
346    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
347    ///   returned instead.
348    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
349    ///   returned instead.
350    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
351    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
352    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
353    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
354    ///   instead.
355    ///
356    /// If you know you'll be using `Nearest`, consider using
357    /// [`Float::power_of_2_of_float_prec_ref`] instead. If you know that your target precision is
358    /// the precision of the input, consider using [`Float::power_of_2_of_float_round_ref`] instead.
359    /// If both of these things are true, consider using the [`PowerOf2`] implementation instead.
360    ///
361    /// # Worst-case complexity
362    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
363    ///
364    /// $M(n, m) = O(n \log n + m)$
365    ///
366    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
367    /// `self.significant_bits()`.
368    ///
369    /// # Panics
370    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
371    /// with the given precision.
372    ///
373    /// # Examples
374    /// ```
375    /// use malachite_base::rounding_modes::RoundingMode::*;
376    /// use malachite_float::Float;
377    /// use std::cmp::Ordering::*;
378    ///
379    /// let x = Float::from(1.5);
380    ///
381    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Floor);
382    /// assert_eq!(p.to_string(), "2.75");
383    /// assert_eq!(o, Less);
384    ///
385    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Ceiling);
386    /// assert_eq!(p.to_string(), "2.88");
387    /// assert_eq!(o, Greater);
388    ///
389    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Nearest);
390    /// assert_eq!(p.to_string(), "2.88");
391    /// assert_eq!(o, Greater);
392    ///
393    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Floor);
394    /// assert_eq!(p.to_string(), "2.8284264");
395    /// assert_eq!(o, Less);
396    ///
397    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Ceiling);
398    /// assert_eq!(p.to_string(), "2.8284302");
399    /// assert_eq!(o, Greater);
400    ///
401    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Nearest);
402    /// assert_eq!(p.to_string(), "2.8284264");
403    /// assert_eq!(o, Less);
404    /// ```
405    pub fn power_of_2_of_float_prec_round_ref(
406        pow: &Self,
407        prec: u64,
408        rm: RoundingMode,
409    ) -> (Self, Ordering) {
410        assert_ne!(prec, 0);
411        match &pow.0 {
412            NaN => (Self::NAN, Equal),
413            // 2^(+inf) = +inf; 2^(-inf) = +0
414            Infinity { sign } => {
415                if *sign {
416                    (Self::INFINITY, Equal)
417                } else {
418                    (Self::ZERO, Equal)
419                }
420            }
421            // 2^(+0) = 2^(-0) = 1
422            Zero { .. } => (Self::one_prec(prec), Equal),
423            Finite { .. } => power_of_2_of_float_prec_round_normal(pow, prec, rm),
424        }
425    }
426
427    #[allow(clippy::needless_pass_by_value)]
428    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
429    /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
430    /// indicating whether the rounded power is less than, equal to, or greater than the exact
431    /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
432    /// `NaN` it also returns `Equal`.
433    ///
434    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
435    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
436    /// the `Nearest` rounding mode.
437    ///
438    /// $$
439    /// f(x,p) = 2^x+\varepsilon.
440    /// $$
441    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
442    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
443    ///
444    /// If the output has a precision, it is `prec`.
445    ///
446    /// Special cases:
447    /// - $f(\text{NaN},p)=\text{NaN}$
448    /// - $f(\infty,p)=\infty$
449    /// - $f(-\infty,p)=0.0$
450    /// - $f(\pm0.0,p)=1.0$
451    ///
452    /// Overflow and underflow:
453    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
454    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
455    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
456    ///
457    /// If you want to use a rounding mode other than `Nearest`, consider using
458    /// [`Float::power_of_2_of_float_prec_round`] instead. If you know that your target precision is
459    /// the precision of the input, consider using the [`PowerOf2`] implementation instead.
460    ///
461    /// # Worst-case complexity
462    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
463    ///
464    /// $M(n, m) = O(n \log n + m)$
465    ///
466    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
467    /// `self.significant_bits()`.
468    ///
469    /// # Panics
470    /// Panics if `prec` is zero.
471    ///
472    /// # Examples
473    /// ```
474    /// use malachite_float::Float;
475    /// use std::cmp::Ordering::*;
476    ///
477    /// let (p, o) = Float::power_of_2_of_float_prec(Float::from(1.5), 5);
478    /// assert_eq!(p.to_string(), "2.88");
479    /// assert_eq!(o, Greater);
480    ///
481    /// let (p, o) = Float::power_of_2_of_float_prec(Float::from(1.5), 20);
482    /// assert_eq!(p.to_string(), "2.8284264");
483    /// assert_eq!(o, Less);
484    /// ```
485    #[inline]
486    pub fn power_of_2_of_float_prec(pow: Self, prec: u64) -> (Self, Ordering) {
487        Self::power_of_2_of_float_prec_round_ref(&pow, prec, Nearest)
488    }
489
490    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
491    /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
492    /// indicating whether the rounded power is less than, equal to, or greater than the exact
493    /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
494    /// `NaN` it also returns `Equal`.
495    ///
496    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
497    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
498    /// the `Nearest` rounding mode.
499    ///
500    /// $$
501    /// f(x,p) = 2^x+\varepsilon.
502    /// $$
503    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
504    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
505    ///
506    /// If the output has a precision, it is `prec`.
507    ///
508    /// Special cases:
509    /// - $f(\text{NaN},p)=\text{NaN}$
510    /// - $f(\infty,p)=\infty$
511    /// - $f(-\infty,p)=0.0$
512    /// - $f(\pm0.0,p)=1.0$
513    ///
514    /// Overflow and underflow:
515    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
516    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
517    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
518    ///
519    /// If you want to use a rounding mode other than `Nearest`, consider using
520    /// [`Float::power_of_2_of_float_prec_round_ref`] instead. If you know that your target
521    /// precision is the precision of the input, consider using the [`PowerOf2`] implementation
522    /// instead.
523    ///
524    /// # Worst-case complexity
525    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
526    ///
527    /// $M(n, m) = O(n \log n + m)$
528    ///
529    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
530    /// `self.significant_bits()`.
531    ///
532    /// # Panics
533    /// Panics if `prec` is zero.
534    ///
535    /// # Examples
536    /// ```
537    /// use malachite_float::Float;
538    /// use std::cmp::Ordering::*;
539    ///
540    /// let x = Float::from(1.5);
541    ///
542    /// let (p, o) = Float::power_of_2_of_float_prec_ref(&x, 5);
543    /// assert_eq!(p.to_string(), "2.88");
544    /// assert_eq!(o, Greater);
545    ///
546    /// let (p, o) = Float::power_of_2_of_float_prec_ref(&x, 20);
547    /// assert_eq!(p.to_string(), "2.8284264");
548    /// assert_eq!(o, Less);
549    /// ```
550    #[inline]
551    pub fn power_of_2_of_float_prec_ref(pow: &Self, prec: u64) -> (Self, Ordering) {
552        Self::power_of_2_of_float_prec_round_ref(pow, prec, Nearest)
553    }
554
555    #[allow(clippy::needless_pass_by_value)]
556    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
557    /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
558    /// the rounded power is less than, equal to, or greater than the exact power. Although `NaN`s
559    /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
560    /// `Equal`.
561    ///
562    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
563    /// description of the possible rounding modes.
564    ///
565    /// $$
566    /// f(x,m) = 2^x+\varepsilon.
567    /// $$
568    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
569    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
570    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
571    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
572    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
573    ///
574    /// If the output has a precision, it is the precision of the input.
575    ///
576    /// Special cases:
577    /// - $f(\text{NaN},m)=\text{NaN}$
578    /// - $f(\infty,m)=\infty$
579    /// - $f(-\infty,m)=0.0$
580    /// - $f(\pm0.0,m)=1.0$
581    ///
582    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on overflow
583    /// and underflow.
584    ///
585    /// If you want to specify an output precision, consider using
586    /// [`Float::power_of_2_of_float_prec_round`] instead. If you know you'll be using the `Nearest`
587    /// rounding mode, consider using the [`PowerOf2`] implementation instead.
588    ///
589    /// # Worst-case complexity
590    /// $T(n) = O(n^{3/2} \log n \log\log n)$
591    ///
592    /// $M(n) = O(n \log n)$
593    ///
594    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
595    ///
596    /// # Panics
597    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
598    /// precision.
599    ///
600    /// # Examples
601    /// ```
602    /// use malachite_base::rounding_modes::RoundingMode::*;
603    /// use malachite_float::Float;
604    /// use std::cmp::Ordering::*;
605    ///
606    /// let (p, o) =
607    ///     Float::power_of_2_of_float_round(Float::from_unsigned_prec(3u32, 100).0 >> 1u32, Floor);
608    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
609    /// assert_eq!(o, Less);
610    ///
611    /// let (p, o) = Float::power_of_2_of_float_round(
612    ///     Float::from_unsigned_prec(3u32, 100).0 >> 1u32,
613    ///     Ceiling,
614    /// );
615    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484215");
616    /// assert_eq!(o, Greater);
617    ///
618    /// let (p, o) = Float::power_of_2_of_float_round(
619    ///     Float::from_unsigned_prec(3u32, 100).0 >> 1u32,
620    ///     Nearest,
621    /// );
622    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
623    /// assert_eq!(o, Less);
624    /// ```
625    #[inline]
626    pub fn power_of_2_of_float_round(pow: Self, rm: RoundingMode) -> (Self, Ordering) {
627        let prec = pow.significant_bits();
628        Self::power_of_2_of_float_prec_round_ref(&pow, prec, rm)
629    }
630
631    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
632    /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
633    /// whether the rounded power is less than, equal to, or greater than the exact power. Although
634    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
635    /// returns `Equal`.
636    ///
637    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
638    /// description of the possible rounding modes.
639    ///
640    /// $$
641    /// f(x,m) = 2^x+\varepsilon.
642    /// $$
643    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
644    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
645    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
646    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
647    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
648    ///
649    /// If the output has a precision, it is the precision of the input.
650    ///
651    /// Special cases:
652    /// - $f(\text{NaN},m)=\text{NaN}$
653    /// - $f(\infty,m)=\infty$
654    /// - $f(-\infty,m)=0.0$
655    /// - $f(\pm0.0,m)=1.0$
656    ///
657    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on overflow
658    /// and underflow.
659    ///
660    /// If you want to specify an output precision, consider using
661    /// [`Float::power_of_2_of_float_prec_round_ref`] instead. If you know you'll be using the
662    /// `Nearest` rounding mode, consider using the [`PowerOf2`] implementation instead.
663    ///
664    /// # Worst-case complexity
665    /// $T(n) = O(n^{3/2} \log n \log\log n)$
666    ///
667    /// $M(n) = O(n \log n)$
668    ///
669    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
670    ///
671    /// # Panics
672    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
673    /// precision.
674    ///
675    /// # Examples
676    /// ```
677    /// use malachite_base::rounding_modes::RoundingMode::*;
678    /// use malachite_float::Float;
679    /// use std::cmp::Ordering::*;
680    ///
681    /// let x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
682    ///
683    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Floor);
684    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
685    /// assert_eq!(o, Less);
686    ///
687    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Ceiling);
688    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484215");
689    /// assert_eq!(o, Greater);
690    ///
691    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Nearest);
692    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
693    /// assert_eq!(o, Less);
694    /// ```
695    #[inline]
696    pub fn power_of_2_of_float_round_ref(pow: &Self, rm: RoundingMode) -> (Self, Ordering) {
697        let prec = pow.significant_bits();
698        Self::power_of_2_of_float_prec_round_ref(pow, prec, rm)
699    }
700
701    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result to the specified
702    /// precision and with the specified rounding mode. An [`Ordering`] is returned, indicating
703    /// whether the rounded power is less than, equal to, or greater than the exact power. Although
704    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
705    /// `NaN` it also returns `Equal`.
706    ///
707    /// See [`RoundingMode`] for a description of the possible rounding modes.
708    ///
709    /// $$
710    /// x \gets 2^x+\varepsilon.
711    /// $$
712    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
713    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
714    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$.
715    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
716    ///   2^{\lfloor\log_2 2^x\rfloor-p}$.
717    ///
718    /// If the output has a precision, it is `prec`.
719    ///
720    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on special
721    /// cases, overflow, and underflow.
722    ///
723    /// If you know you'll be using `Nearest`, consider using
724    /// [`Float::power_of_2_of_float_prec_assign`] instead. If you know that your target precision
725    /// is the precision of the input, consider using [`Float::power_of_2_of_float_round_assign`]
726    /// instead. If both of these things are true, consider using the [`PowerOf2Assign`]
727    /// implementation instead.
728    ///
729    /// # Worst-case complexity
730    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
731    ///
732    /// $M(n, m) = O(n \log n + m)$
733    ///
734    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
735    /// `self.significant_bits()`.
736    ///
737    /// # Panics
738    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
739    /// with the given precision.
740    ///
741    /// # Examples
742    /// ```
743    /// use malachite_base::rounding_modes::RoundingMode::*;
744    /// use malachite_float::Float;
745    /// use std::cmp::Ordering::*;
746    ///
747    /// let mut x = Float::from(1.5);
748    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Floor), Less);
749    /// assert_eq!(x.to_string(), "2.75");
750    ///
751    /// let mut x = Float::from(1.5);
752    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Ceiling), Greater);
753    /// assert_eq!(x.to_string(), "2.88");
754    ///
755    /// let mut x = Float::from(1.5);
756    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Nearest), Greater);
757    /// assert_eq!(x.to_string(), "2.88");
758    ///
759    /// let mut x = Float::from(1.5);
760    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(20, Floor), Less);
761    /// assert_eq!(x.to_string(), "2.8284264");
762    ///
763    /// let mut x = Float::from(1.5);
764    /// assert_eq!(
765    ///     x.power_of_2_of_float_prec_round_assign(20, Ceiling),
766    ///     Greater
767    /// );
768    /// assert_eq!(x.to_string(), "2.8284302");
769    ///
770    /// let mut x = Float::from(1.5);
771    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(20, Nearest), Less);
772    /// assert_eq!(x.to_string(), "2.8284264");
773    /// ```
774    #[inline]
775    pub fn power_of_2_of_float_prec_round_assign(
776        &mut self,
777        prec: u64,
778        rm: RoundingMode,
779    ) -> Ordering {
780        let (result, o) = Self::power_of_2_of_float_prec_round_ref(self, prec, rm);
781        *self = result;
782        o
783    }
784
785    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result to the nearest value
786    /// of the specified precision. An [`Ordering`] is returned, indicating whether the rounded
787    /// power is less than, equal to, or greater than the exact power. Although `NaN`s are not
788    /// comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
789    /// returns `Equal`.
790    ///
791    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
792    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
793    /// the `Nearest` rounding mode.
794    ///
795    /// $$
796    /// x \gets 2^x+\varepsilon.
797    /// $$
798    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
799    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
800    ///
801    /// If the output has a precision, it is `prec`.
802    ///
803    /// See the [`Float::power_of_2_of_float_prec`] documentation for information on special cases,
804    /// overflow, and underflow.
805    ///
806    /// If you want to use a rounding mode other than `Nearest`, consider using
807    /// [`Float::power_of_2_of_float_prec_round_assign`] instead. If you know that your target
808    /// precision is the precision of the input, consider using the [`PowerOf2Assign`]
809    /// implementation instead.
810    ///
811    /// # Worst-case complexity
812    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
813    ///
814    /// $M(n, m) = O(n \log n + m)$
815    ///
816    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
817    /// `self.significant_bits()`.
818    ///
819    /// # Panics
820    /// Panics if `prec` is zero.
821    ///
822    /// # Examples
823    /// ```
824    /// use malachite_float::Float;
825    /// use std::cmp::Ordering::*;
826    ///
827    /// let mut x = Float::from(1.5);
828    /// assert_eq!(x.power_of_2_of_float_prec_assign(5), Greater);
829    /// assert_eq!(x.to_string(), "2.88");
830    ///
831    /// let mut x = Float::from(1.5);
832    /// assert_eq!(x.power_of_2_of_float_prec_assign(20), Less);
833    /// assert_eq!(x.to_string(), "2.8284264");
834    /// ```
835    #[inline]
836    pub fn power_of_2_of_float_prec_assign(&mut self, prec: u64) -> Ordering {
837        self.power_of_2_of_float_prec_round_assign(prec, Nearest)
838    }
839
840    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result with the specified
841    /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded power is less
842    /// than, equal to, or greater than the exact power. Although `NaN`s are not comparable to any
843    /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
844    ///
845    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
846    /// description of the possible rounding modes.
847    ///
848    /// $$
849    /// x \gets 2^x+\varepsilon.
850    /// $$
851    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
852    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
853    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
854    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
855    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
856    ///
857    /// If the output has a precision, it is the precision of the input.
858    ///
859    /// See the [`Float::power_of_2_of_float_round`] documentation for information on special cases,
860    /// overflow, and underflow.
861    ///
862    /// If you want to specify an output precision, consider using
863    /// [`Float::power_of_2_of_float_prec_round_assign`] instead. If you know you'll be using the
864    /// `Nearest` rounding mode, consider using the [`PowerOf2Assign`] implementation instead.
865    ///
866    /// # Worst-case complexity
867    /// $T(n) = O(n^{3/2} \log n \log\log n)$
868    ///
869    /// $M(n) = O(n \log n)$
870    ///
871    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
872    ///
873    /// # Panics
874    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
875    /// precision.
876    ///
877    /// # Examples
878    /// ```
879    /// use malachite_base::rounding_modes::RoundingMode::*;
880    /// use malachite_float::Float;
881    /// use std::cmp::Ordering::*;
882    ///
883    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
884    /// assert_eq!(x.power_of_2_of_float_round_assign(Floor), Less);
885    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
886    ///
887    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
888    /// assert_eq!(x.power_of_2_of_float_round_assign(Ceiling), Greater);
889    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484215");
890    ///
891    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
892    /// assert_eq!(x.power_of_2_of_float_round_assign(Nearest), Less);
893    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
894    /// ```
895    #[inline]
896    pub fn power_of_2_of_float_round_assign(&mut self, rm: RoundingMode) -> Ordering {
897        let prec = self.significant_bits();
898        self.power_of_2_of_float_prec_round_assign(prec, rm)
899    }
900
901    #[allow(clippy::needless_pass_by_value)]
902    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
903    /// and with the specified rounding mode and returning the result as a [`Float`]. The
904    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
905    /// rounded power is less than, equal to, or greater than the exact power.
906    ///
907    /// See [`RoundingMode`] for a description of the possible rounding modes.
908    ///
909    /// $$
910    /// f(x,p,m) = 2^x+\varepsilon.
911    /// $$
912    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p+1}$.
913    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$.
914    ///
915    /// These bounds do not apply when the result overflows or underflows; see below.
916    ///
917    /// The output has precision `prec`.
918    ///
919    /// Special cases:
920    /// - $f(0,p,m)=1$.
921    ///
922    /// Overflow and underflow:
923    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
924    ///   returned instead.
925    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
926    ///   returned instead.
927    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
928    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
929    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
930    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
931    ///   instead.
932    ///
933    /// If you know you'll be using `Nearest`, consider using [`Float::power_of_2_rational_prec`]
934    /// instead.
935    ///
936    /// # Worst-case complexity
937    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
938    ///
939    /// $M(n, m) = O(n \log n + m \log m)$
940    ///
941    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
942    /// `x.significant_bits()`.
943    ///
944    /// # Panics
945    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
946    /// with the given precision (which is the case whenever $x$ is not an integer).
947    ///
948    /// # Examples
949    /// ```
950    /// use malachite_base::rounding_modes::RoundingMode::*;
951    /// use malachite_float::Float;
952    /// use malachite_q::Rational;
953    /// use std::cmp::Ordering::*;
954    ///
955    /// let (p, o) =
956    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
957    /// assert_eq!(p.to_string(), "1.50");
958    /// assert_eq!(o, Less);
959    ///
960    /// let (p, o) =
961    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
962    /// assert_eq!(p.to_string(), "1.56");
963    /// assert_eq!(o, Greater);
964    ///
965    /// let (p, o) =
966    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
967    /// assert_eq!(p.to_string(), "1.5157166");
968    /// assert_eq!(o, Less);
969    ///
970    /// let (p, o) =
971    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
972    /// assert_eq!(p.to_string(), "1.5157185");
973    /// assert_eq!(o, Greater);
974    /// ```
975    #[inline]
976    pub fn power_of_2_rational_prec_round(
977        x: Rational,
978        prec: u64,
979        rm: RoundingMode,
980    ) -> (Self, Ordering) {
981        Self::power_of_2_rational_prec_round_ref(&x, prec, rm)
982    }
983
984    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
985    /// and with the specified rounding mode and returning the result as a [`Float`]. The
986    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
987    /// rounded power is less than, equal to, or greater than the exact power.
988    ///
989    /// See [`RoundingMode`] for a description of the possible rounding modes.
990    ///
991    /// $$
992    /// f(x,p,m) = 2^x+\varepsilon.
993    /// $$
994    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p+1}$.
995    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$.
996    ///
997    /// These bounds do not apply when the result overflows or underflows; see below.
998    ///
999    /// The output has precision `prec`.
1000    ///
1001    /// Special cases:
1002    /// - $f(0,p,m)=1$.
1003    ///
1004    /// Overflow and underflow:
1005    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1006    ///   returned instead.
1007    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1008    ///   returned instead.
1009    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1010    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1011    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1012    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1013    ///   instead.
1014    ///
1015    /// If you know you'll be using `Nearest`, consider using
1016    /// [`Float::power_of_2_rational_prec_ref`] instead.
1017    ///
1018    /// # Worst-case complexity
1019    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1020    ///
1021    /// $M(n, m) = O(n \log n + m \log m)$
1022    ///
1023    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1024    /// `x.significant_bits()`.
1025    ///
1026    /// # Panics
1027    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1028    /// with the given precision (which is the case whenever $x$ is not an integer).
1029    ///
1030    /// # Examples
1031    /// ```
1032    /// use malachite_base::rounding_modes::RoundingMode::*;
1033    /// use malachite_float::Float;
1034    /// use malachite_q::Rational;
1035    /// use std::cmp::Ordering::*;
1036    ///
1037    /// let (p, o) =
1038    ///     Float::power_of_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1039    /// assert_eq!(p.to_string(), "1.50");
1040    /// assert_eq!(o, Less);
1041    ///
1042    /// let (p, o) = Float::power_of_2_rational_prec_round_ref(
1043    ///     &Rational::from_unsigneds(3u8, 5),
1044    ///     5,
1045    ///     Ceiling,
1046    /// );
1047    /// assert_eq!(p.to_string(), "1.56");
1048    /// assert_eq!(o, Greater);
1049    ///
1050    /// let (p, o) =
1051    ///     Float::power_of_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1052    /// assert_eq!(p.to_string(), "1.5157166");
1053    /// assert_eq!(o, Less);
1054    ///
1055    /// let (p, o) = Float::power_of_2_rational_prec_round_ref(
1056    ///     &Rational::from_unsigneds(3u8, 5),
1057    ///     20,
1058    ///     Ceiling,
1059    /// );
1060    /// assert_eq!(p.to_string(), "1.5157185");
1061    /// assert_eq!(o, Greater);
1062    /// ```
1063    pub fn power_of_2_rational_prec_round_ref(
1064        x: &Rational,
1065        prec: u64,
1066        rm: RoundingMode,
1067    ) -> (Self, Ordering) {
1068        assert_ne!(prec, 0);
1069        // If x is an integer, 2^x is exactly a power of 2 (this includes 2^0 = 1). Handle it
1070        // directly: the Ziv loop in the helper never converges on an exactly-representable result.
1071        if let Ok(n) = Integer::try_from(x) {
1072            return if let Ok(pow) = i64::try_from(&n) {
1073                // `power_of_2_prec_round` handles its own overflow and underflow.
1074                Self::power_of_2_prec_round(pow, prec, rm)
1075            } else if x.sign() == Greater {
1076                // x is too large to fit in an i64, so 2^x overflows.
1077                exp_overflow(prec, rm)
1078            } else {
1079                exp_underflow(prec, rm)
1080            };
1081        }
1082        power_of_2_rational_helper(x, prec, rm)
1083    }
1084
1085    #[allow(clippy::needless_pass_by_value)]
1086    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of the
1087    /// specified precision and returning the result as a [`Float`]. The [`Rational`] is taken by
1088    /// value. An [`Ordering`] is also returned, indicating whether the rounded power is less than,
1089    /// equal to, or greater than the exact power.
1090    ///
1091    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1092    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1093    /// the `Nearest` rounding mode.
1094    ///
1095    /// $$
1096    /// f(x,p) = 2^x+\varepsilon,
1097    /// $$
1098    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$ (unless the result overflows or
1099    /// underflows; see below).
1100    ///
1101    /// The output has precision `prec`.
1102    ///
1103    /// Special cases:
1104    /// - $f(0,p)=1$.
1105    ///
1106    /// Overflow and underflow:
1107    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1108    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1109    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1110    ///
1111    /// If you want to use a rounding mode other than `Nearest`, consider using
1112    /// [`Float::power_of_2_rational_prec_round`] instead.
1113    ///
1114    /// # Worst-case complexity
1115    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1116    ///
1117    /// $M(n, m) = O(n \log n + m \log m)$
1118    ///
1119    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1120    /// `x.significant_bits()`.
1121    ///
1122    /// # Panics
1123    /// Panics if `prec` is zero.
1124    ///
1125    /// # Examples
1126    /// ```
1127    /// use malachite_base::num::basic::traits::Zero;
1128    /// use malachite_float::Float;
1129    /// use malachite_q::Rational;
1130    /// use std::cmp::Ordering::*;
1131    ///
1132    /// let (p, o) = Float::power_of_2_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1133    /// assert_eq!(p.to_string(), "1.50");
1134    /// assert_eq!(o, Less);
1135    ///
1136    /// let (p, o) = Float::power_of_2_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1137    /// assert_eq!(p.to_string(), "1.5157166");
1138    /// assert_eq!(o, Less);
1139    ///
1140    /// let (p, o) = Float::power_of_2_rational_prec(Rational::ZERO, 10);
1141    /// assert_eq!(p.to_string(), "1.0000");
1142    /// assert_eq!(o, Equal);
1143    /// ```
1144    #[inline]
1145    pub fn power_of_2_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1146        Self::power_of_2_rational_prec_round_ref(&x, prec, Nearest)
1147    }
1148
1149    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of the
1150    /// specified precision and returning the result as a [`Float`]. The [`Rational`] is taken by
1151    /// reference. An [`Ordering`] is also returned, indicating whether the rounded power is less
1152    /// than, equal to, or greater than the exact power.
1153    ///
1154    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1155    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1156    /// the `Nearest` rounding mode.
1157    ///
1158    /// $$
1159    /// f(x,p) = 2^x+\varepsilon,
1160    /// $$
1161    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$ (unless the result overflows or
1162    /// underflows; see below).
1163    ///
1164    /// The output has precision `prec`.
1165    ///
1166    /// Special cases:
1167    /// - $f(0,p)=1$.
1168    ///
1169    /// Overflow and underflow:
1170    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1171    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1172    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1173    ///
1174    /// If you want to use a rounding mode other than `Nearest`, consider using
1175    /// [`Float::power_of_2_rational_prec_round_ref`] instead.
1176    ///
1177    /// # Worst-case complexity
1178    /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1179    ///
1180    /// $M(n, m) = O(n \log n + m \log m)$
1181    ///
1182    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1183    /// `x.significant_bits()`.
1184    ///
1185    /// # Panics
1186    /// Panics if `prec` is zero.
1187    ///
1188    /// # Examples
1189    /// ```
1190    /// use malachite_base::num::basic::traits::Zero;
1191    /// use malachite_float::Float;
1192    /// use malachite_q::Rational;
1193    /// use std::cmp::Ordering::*;
1194    ///
1195    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1196    /// assert_eq!(p.to_string(), "1.50");
1197    /// assert_eq!(o, Less);
1198    ///
1199    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1200    /// assert_eq!(p.to_string(), "1.5157166");
1201    /// assert_eq!(o, Less);
1202    ///
1203    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::ZERO, 10);
1204    /// assert_eq!(p.to_string(), "1.0000");
1205    /// assert_eq!(o, Equal);
1206    /// ```
1207    #[inline]
1208    pub fn power_of_2_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1209        Self::power_of_2_rational_prec_round_ref(x, prec, Nearest)
1210    }
1211}
1212
1213impl PowerOf2<Self> for Float {
1214    /// Computes $2^x$, where $x$ is a [`Float`], taking it by value.
1215    ///
1216    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1217    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1218    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1219    ///
1220    /// $$
1221    /// f(x) = 2^x+\varepsilon.
1222    /// $$
1223    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1224    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1225    ///   where $p$ is the precision of the input.
1226    ///
1227    /// Special cases:
1228    /// - $f(\text{NaN})=\text{NaN}$
1229    /// - $f(\infty)=\infty$
1230    /// - $f(-\infty)=0.0$
1231    /// - $f(\pm0.0)=1.0$
1232    ///
1233    /// See the [`Float::power_of_2_of_float_round`] documentation for information on overflow and
1234    /// underflow.
1235    ///
1236    /// If you want to use a rounding mode other than `Nearest`, consider using
1237    /// [`Float::power_of_2_of_float_round`] instead. If you want to specify the output precision,
1238    /// consider using [`Float::power_of_2_of_float_prec`]. If you want both of these things,
1239    /// consider using [`Float::power_of_2_of_float_prec_round`].
1240    ///
1241    /// # Worst-case complexity
1242    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1243    ///
1244    /// $M(n) = O(n \log n)$
1245    ///
1246    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1247    ///
1248    /// # Examples
1249    /// ```
1250    /// use malachite_base::num::arithmetic::traits::PowerOf2;
1251    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1252    /// use malachite_float::Float;
1253    ///
1254    /// assert!(Float::power_of_2(Float::NAN).is_nan());
1255    /// assert_eq!(Float::power_of_2(Float::INFINITY), Float::INFINITY);
1256    /// assert_eq!(Float::power_of_2(Float::NEGATIVE_INFINITY), Float::ZERO);
1257    /// assert_eq!(
1258    ///     Float::power_of_2(Float::from_unsigned_prec(3u32, 100).0 >> 1u32).to_string(),
1259    ///     "2.8284271247461900976033774484184"
1260    /// );
1261    /// ```
1262    #[inline]
1263    fn power_of_2(pow: Self) -> Self {
1264        Self::power_of_2_of_float_round(pow, Nearest).0
1265    }
1266}
1267
1268impl PowerOf2<&Self> for Float {
1269    /// Computes $2^x$, where $x$ is a [`Float`], taking it by reference.
1270    ///
1271    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1272    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1273    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1274    ///
1275    /// $$
1276    /// f(x) = 2^x+\varepsilon.
1277    /// $$
1278    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1279    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1280    ///   where $p$ is the precision of the input.
1281    ///
1282    /// Special cases:
1283    /// - $f(\text{NaN})=\text{NaN}$
1284    /// - $f(\infty)=\infty$
1285    /// - $f(-\infty)=0.0$
1286    /// - $f(\pm0.0)=1.0$
1287    ///
1288    /// See the [`Float::power_of_2_of_float_round`] documentation for information on overflow and
1289    /// underflow.
1290    ///
1291    /// If you want to use a rounding mode other than `Nearest`, consider using
1292    /// [`Float::power_of_2_of_float_round_ref`] instead. If you want to specify the output
1293    /// precision, consider using [`Float::power_of_2_of_float_prec_ref`]. If you want both of these
1294    /// things, consider using [`Float::power_of_2_of_float_prec_round_ref`].
1295    ///
1296    /// # Worst-case complexity
1297    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1298    ///
1299    /// $M(n) = O(n \log n)$
1300    ///
1301    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1302    ///
1303    /// # Examples
1304    /// ```
1305    /// use malachite_base::num::arithmetic::traits::PowerOf2;
1306    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1307    /// use malachite_float::Float;
1308    ///
1309    /// assert!(Float::power_of_2(&Float::NAN).is_nan());
1310    /// assert_eq!(Float::power_of_2(&Float::INFINITY), Float::INFINITY);
1311    /// assert_eq!(Float::power_of_2(&Float::NEGATIVE_INFINITY), Float::ZERO);
1312    /// assert_eq!(
1313    ///     Float::power_of_2(&(Float::from_unsigned_prec(3u32, 100).0 >> 1u32)).to_string(),
1314    ///     "2.8284271247461900976033774484184"
1315    /// );
1316    /// ```
1317    #[inline]
1318    fn power_of_2(pow: &Self) -> Self {
1319        Self::power_of_2_of_float_round_ref(pow, Nearest).0
1320    }
1321}
1322
1323impl PowerOf2Assign for Float {
1324    /// Computes $2^x$, where $x$ is a [`Float`], in place.
1325    ///
1326    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1327    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1328    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1329    ///
1330    /// $$
1331    /// x \gets 2^x+\varepsilon.
1332    /// $$
1333    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1334    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1335    ///   where $p$ is the precision of the input.
1336    ///
1337    /// See the [`Float::power_of_2_of_float_round`] documentation for information on special cases,
1338    /// overflow, and underflow.
1339    ///
1340    /// If you want to use a rounding mode other than `Nearest`, consider using
1341    /// [`Float::power_of_2_of_float_round_assign`] instead. If you want to specify the output
1342    /// precision, consider using [`Float::power_of_2_of_float_prec_assign`]. If you want both of
1343    /// these things, consider using [`Float::power_of_2_of_float_prec_round_assign`].
1344    ///
1345    /// # Worst-case complexity
1346    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1347    ///
1348    /// $M(n) = O(n \log n)$
1349    ///
1350    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1351    ///
1352    /// # Examples
1353    /// ```
1354    /// use malachite_base::num::arithmetic::traits::PowerOf2Assign;
1355    /// use malachite_float::Float;
1356    ///
1357    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
1358    /// x.power_of_2_assign();
1359    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
1360    /// ```
1361    #[inline]
1362    fn power_of_2_assign(&mut self) {
1363        self.power_of_2_of_float_round_assign(Nearest);
1364    }
1365}
1366
1367/// Computes $2^x$, where $x$ is a primitive float, returning the result as a primitive float of the
1368/// same type. Using this function is more accurate than using `x.exp2()` or the `exp2` function
1369/// provided by `libm`.
1370///
1371/// $$
1372/// f(x) = 2^x+\varepsilon.
1373/// $$
1374/// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1375/// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$, where
1376///   $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1377///   [`f64`], but less if the output is subnormal).
1378///
1379/// Special cases:
1380/// - $f(\text{NaN})=\text{NaN}$
1381/// - $f(\infty)=\infty$
1382/// - $f(-\infty)=0.0$
1383/// - $f(\pm0.0)=1.0$
1384///
1385/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1386/// `x` gives `0.0`.
1387///
1388/// # Worst-case complexity
1389/// Constant time and additional memory.
1390///
1391/// # Examples
1392/// ```
1393/// use malachite_base::num::basic::traits::NegativeInfinity;
1394/// use malachite_base::num::float::NiceFloat;
1395/// use malachite_float::float::arithmetic::power_of_2_of_float::primitive_float_power_of_2;
1396///
1397/// assert!(primitive_float_power_of_2(f32::NAN).is_nan());
1398/// assert_eq!(
1399///     NiceFloat(primitive_float_power_of_2(f32::INFINITY)),
1400///     NiceFloat(f32::INFINITY)
1401/// );
1402/// assert_eq!(
1403///     NiceFloat(primitive_float_power_of_2(f32::NEGATIVE_INFINITY)),
1404///     NiceFloat(0.0)
1405/// );
1406/// assert_eq!(
1407///     NiceFloat(primitive_float_power_of_2(0.0f32)),
1408///     NiceFloat(1.0)
1409/// );
1410/// assert_eq!(
1411///     NiceFloat(primitive_float_power_of_2(1.0f32)),
1412///     NiceFloat(2.0)
1413/// );
1414/// assert_eq!(
1415///     NiceFloat(primitive_float_power_of_2(0.5f32)),
1416///     NiceFloat(1.4142135)
1417/// );
1418/// ```
1419#[inline]
1420#[allow(clippy::type_repetition_in_bounds)]
1421pub fn primitive_float_power_of_2<T: PrimitiveFloat>(x: T) -> T
1422where
1423    Float: From<T> + PartialOrd<T>,
1424    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1425{
1426    emulate_float_to_float_fn(Float::power_of_2_of_float_prec, x)
1427}
1428
1429/// Computes $2^x$, where $x$ is a [`Rational`], returning the result as a primitive float.
1430///
1431/// $$
1432/// f(x) = 2^x+\varepsilon.
1433/// $$
1434/// - If $2^x$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
1435/// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$, where
1436///   $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1437///   [`f64`], but less if the output is subnormal).
1438///
1439/// Special cases:
1440/// - $f(0)=1$
1441///
1442/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1443/// `x` gives `0.0`.
1444///
1445/// # Worst-case complexity
1446/// $T(m) = O(m (\log m)^2 \log\log m)$
1447///
1448/// $M(m) = O(m \log m)$
1449///
1450/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
1451///
1452/// # Examples
1453/// ```
1454/// use malachite_base::num::basic::traits::Zero;
1455/// use malachite_base::num::float::NiceFloat;
1456/// use malachite_float::float::arithmetic::power_of_2_of_float::*;
1457/// use malachite_q::Rational;
1458///
1459/// assert_eq!(
1460///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::ZERO)),
1461///     NiceFloat(1.0)
1462/// );
1463/// assert_eq!(
1464///     NiceFloat(primitive_float_power_of_2_rational::<f64>(
1465///         &Rational::from_unsigneds(1u8, 3)
1466///     )),
1467///     NiceFloat(1.2599210498948732)
1468/// );
1469/// assert_eq!(
1470///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::from(
1471///         10000
1472///     ))),
1473///     NiceFloat(f64::INFINITY)
1474/// );
1475/// assert_eq!(
1476///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::from(
1477///         -10000
1478///     ))),
1479///     NiceFloat(0.0)
1480/// );
1481/// ```
1482#[inline]
1483#[allow(clippy::type_repetition_in_bounds)]
1484pub fn primitive_float_power_of_2_rational<T: PrimitiveFloat>(x: &Rational) -> T
1485where
1486    Float: PartialOrd<T>,
1487    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1488{
1489    emulate_rational_to_float_fn(Float::power_of_2_rational_prec_ref, x)
1490}