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_extras::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) = O(n^{3/2} \log n \log\log n)$
271    ///
272    /// $M(n) = O(n \log n)$
273    ///
274    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
275    ///
276    /// # Panics
277    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
278    /// with the given precision.
279    ///
280    /// # Examples
281    /// ```
282    /// use malachite_base::rounding_modes::RoundingMode::*;
283    /// use malachite_float::Float;
284    /// use std::cmp::Ordering::*;
285    ///
286    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Floor);
287    /// assert_eq!(p.to_string(), "2.75");
288    /// assert_eq!(o, Less);
289    ///
290    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Ceiling);
291    /// assert_eq!(p.to_string(), "2.88");
292    /// assert_eq!(o, Greater);
293    ///
294    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 5, Nearest);
295    /// assert_eq!(p.to_string(), "2.88");
296    /// assert_eq!(o, Greater);
297    ///
298    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Floor);
299    /// assert_eq!(p.to_string(), "2.8284264");
300    /// assert_eq!(o, Less);
301    ///
302    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Ceiling);
303    /// assert_eq!(p.to_string(), "2.8284302");
304    /// assert_eq!(o, Greater);
305    ///
306    /// let (p, o) = Float::power_of_2_of_float_prec_round(Float::from(1.5), 20, Nearest);
307    /// assert_eq!(p.to_string(), "2.8284264");
308    /// assert_eq!(o, Less);
309    /// ```
310    #[inline]
311    pub fn power_of_2_of_float_prec_round(
312        pow: Self,
313        prec: u64,
314        rm: RoundingMode,
315    ) -> (Self, Ordering) {
316        Self::power_of_2_of_float_prec_round_ref(&pow, prec, rm)
317    }
318
319    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the specified precision and
320    /// with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is
321    /// also returned, indicating whether the rounded power is less than, equal to, or greater than
322    /// the exact power. Although `NaN`s are not comparable to any [`Float`], whenever this function
323    /// returns a `NaN` it also returns `Equal`.
324    ///
325    /// See [`RoundingMode`] for a description of the possible rounding modes.
326    ///
327    /// $$
328    /// f(x,p,m) = 2^x+\varepsilon.
329    /// $$
330    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
331    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
332    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$.
333    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
334    ///   2^{\lfloor\log_2 2^x\rfloor-p}$.
335    ///
336    /// If the output has a precision, it is `prec`.
337    ///
338    /// Special cases:
339    /// - $f(\text{NaN},p,m)=\text{NaN}$
340    /// - $f(\infty,p,m)=\infty$
341    /// - $f(-\infty,p,m)=0.0$
342    /// - $f(\pm0.0,p,m)=1.0$
343    ///
344    /// Overflow and underflow:
345    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
346    ///   returned instead.
347    /// - 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
348    ///   returned instead.
349    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
350    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
351    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
352    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
353    ///   instead.
354    ///
355    /// If you know you'll be using `Nearest`, consider using
356    /// [`Float::power_of_2_of_float_prec_ref`] instead. If you know that your target precision is
357    /// the precision of the input, consider using [`Float::power_of_2_of_float_round_ref`] instead.
358    /// If both of these things are true, consider using the [`PowerOf2`] implementation instead.
359    ///
360    /// # Worst-case complexity
361    /// $T(n) = O(n^{3/2} \log n \log\log n)$
362    ///
363    /// $M(n) = O(n \log n)$
364    ///
365    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
366    ///
367    /// # Panics
368    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
369    /// with the given precision.
370    ///
371    /// # Examples
372    /// ```
373    /// use malachite_base::rounding_modes::RoundingMode::*;
374    /// use malachite_float::Float;
375    /// use std::cmp::Ordering::*;
376    ///
377    /// let x = Float::from(1.5);
378    ///
379    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Floor);
380    /// assert_eq!(p.to_string(), "2.75");
381    /// assert_eq!(o, Less);
382    ///
383    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Ceiling);
384    /// assert_eq!(p.to_string(), "2.88");
385    /// assert_eq!(o, Greater);
386    ///
387    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 5, Nearest);
388    /// assert_eq!(p.to_string(), "2.88");
389    /// assert_eq!(o, Greater);
390    ///
391    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Floor);
392    /// assert_eq!(p.to_string(), "2.8284264");
393    /// assert_eq!(o, Less);
394    ///
395    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Ceiling);
396    /// assert_eq!(p.to_string(), "2.8284302");
397    /// assert_eq!(o, Greater);
398    ///
399    /// let (p, o) = Float::power_of_2_of_float_prec_round_ref(&x, 20, Nearest);
400    /// assert_eq!(p.to_string(), "2.8284264");
401    /// assert_eq!(o, Less);
402    /// ```
403    pub fn power_of_2_of_float_prec_round_ref(
404        pow: &Self,
405        prec: u64,
406        rm: RoundingMode,
407    ) -> (Self, Ordering) {
408        assert_ne!(prec, 0);
409        match &pow.0 {
410            NaN => (Self::NAN, Equal),
411            // 2^(+inf) = +inf; 2^(-inf) = +0
412            Infinity { sign } => {
413                if *sign {
414                    (Self::INFINITY, Equal)
415                } else {
416                    (Self::ZERO, Equal)
417                }
418            }
419            // 2^(+0) = 2^(-0) = 1
420            Zero { .. } => (Self::one_prec(prec), Equal),
421            Finite { .. } => power_of_2_of_float_prec_round_normal(pow, prec, rm),
422        }
423    }
424
425    #[allow(clippy::needless_pass_by_value)]
426    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
427    /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
428    /// indicating whether the rounded power is less than, equal to, or greater than the exact
429    /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
430    /// `NaN` it also returns `Equal`.
431    ///
432    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
433    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
434    /// the `Nearest` rounding mode.
435    ///
436    /// $$
437    /// f(x,p) = 2^x+\varepsilon.
438    /// $$
439    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
440    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
441    ///
442    /// If the output has a precision, it is `prec`.
443    ///
444    /// Special cases:
445    /// - $f(\text{NaN},p)=\text{NaN}$
446    /// - $f(\infty,p)=\infty$
447    /// - $f(-\infty,p)=0.0$
448    /// - $f(\pm0.0,p)=1.0$
449    ///
450    /// Overflow and underflow:
451    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
452    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
453    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
454    ///
455    /// If you want to use a rounding mode other than `Nearest`, consider using
456    /// [`Float::power_of_2_of_float_prec_round`] instead. If you know that your target precision is
457    /// the precision of the input, consider using the [`PowerOf2`] implementation instead.
458    ///
459    /// # Worst-case complexity
460    /// $T(n) = O(n^{3/2} \log n \log\log n)$
461    ///
462    /// $M(n) = O(n \log n)$
463    ///
464    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
465    ///
466    /// # Panics
467    /// Panics if `prec` is zero.
468    ///
469    /// # Examples
470    /// ```
471    /// use malachite_float::Float;
472    /// use std::cmp::Ordering::*;
473    ///
474    /// let (p, o) = Float::power_of_2_of_float_prec(Float::from(1.5), 5);
475    /// assert_eq!(p.to_string(), "2.88");
476    /// assert_eq!(o, Greater);
477    ///
478    /// let (p, o) = Float::power_of_2_of_float_prec(Float::from(1.5), 20);
479    /// assert_eq!(p.to_string(), "2.8284264");
480    /// assert_eq!(o, Less);
481    /// ```
482    #[inline]
483    pub fn power_of_2_of_float_prec(pow: Self, prec: u64) -> (Self, Ordering) {
484        Self::power_of_2_of_float_prec_round_ref(&pow, prec, Nearest)
485    }
486
487    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result to the nearest value of the
488    /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
489    /// indicating whether the rounded power is less than, equal to, or greater than the exact
490    /// power. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
491    /// `NaN` it also returns `Equal`.
492    ///
493    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
494    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
495    /// the `Nearest` rounding mode.
496    ///
497    /// $$
498    /// f(x,p) = 2^x+\varepsilon.
499    /// $$
500    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
501    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
502    ///
503    /// If the output has a precision, it is `prec`.
504    ///
505    /// Special cases:
506    /// - $f(\text{NaN},p)=\text{NaN}$
507    /// - $f(\infty,p)=\infty$
508    /// - $f(-\infty,p)=0.0$
509    /// - $f(\pm0.0,p)=1.0$
510    ///
511    /// Overflow and underflow:
512    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
513    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
514    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
515    ///
516    /// If you want to use a rounding mode other than `Nearest`, consider using
517    /// [`Float::power_of_2_of_float_prec_round_ref`] instead. If you know that your target
518    /// precision is the precision of the input, consider using the [`PowerOf2`] implementation
519    /// instead.
520    ///
521    /// # Worst-case complexity
522    /// $T(n) = O(n^{3/2} \log n \log\log n)$
523    ///
524    /// $M(n) = O(n \log n)$
525    ///
526    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
527    ///
528    /// # Panics
529    /// Panics if `prec` is zero.
530    ///
531    /// # Examples
532    /// ```
533    /// use malachite_float::Float;
534    /// use std::cmp::Ordering::*;
535    ///
536    /// let x = Float::from(1.5);
537    ///
538    /// let (p, o) = Float::power_of_2_of_float_prec_ref(&x, 5);
539    /// assert_eq!(p.to_string(), "2.88");
540    /// assert_eq!(o, Greater);
541    ///
542    /// let (p, o) = Float::power_of_2_of_float_prec_ref(&x, 20);
543    /// assert_eq!(p.to_string(), "2.8284264");
544    /// assert_eq!(o, Less);
545    /// ```
546    #[inline]
547    pub fn power_of_2_of_float_prec_ref(pow: &Self, prec: u64) -> (Self, Ordering) {
548        Self::power_of_2_of_float_prec_round_ref(pow, prec, Nearest)
549    }
550
551    #[allow(clippy::needless_pass_by_value)]
552    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
553    /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
554    /// the rounded power is less than, equal to, or greater than the exact power. Although `NaN`s
555    /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
556    /// `Equal`.
557    ///
558    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
559    /// description of the possible rounding modes.
560    ///
561    /// $$
562    /// f(x,m) = 2^x+\varepsilon.
563    /// $$
564    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
565    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
566    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
567    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
568    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
569    ///
570    /// If the output has a precision, it is the precision of the input.
571    ///
572    /// Special cases:
573    /// - $f(\text{NaN},m)=\text{NaN}$
574    /// - $f(\infty,m)=\infty$
575    /// - $f(-\infty,m)=0.0$
576    /// - $f(\pm0.0,m)=1.0$
577    ///
578    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on overflow
579    /// and underflow.
580    ///
581    /// If you want to specify an output precision, consider using
582    /// [`Float::power_of_2_of_float_prec_round`] instead. If you know you'll be using the `Nearest`
583    /// rounding mode, consider using the [`PowerOf2`] implementation instead.
584    ///
585    /// # Worst-case complexity
586    /// $T(n) = O(n^{3/2} \log n \log\log n)$
587    ///
588    /// $M(n) = O(n \log n)$
589    ///
590    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
591    ///
592    /// # Panics
593    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
594    /// precision.
595    ///
596    /// # Examples
597    /// ```
598    /// use malachite_base::rounding_modes::RoundingMode::*;
599    /// use malachite_float::Float;
600    /// use std::cmp::Ordering::*;
601    ///
602    /// let (p, o) =
603    ///     Float::power_of_2_of_float_round(Float::from_unsigned_prec(3u32, 100).0 >> 1u32, Floor);
604    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
605    /// assert_eq!(o, Less);
606    ///
607    /// let (p, o) = Float::power_of_2_of_float_round(
608    ///     Float::from_unsigned_prec(3u32, 100).0 >> 1u32,
609    ///     Ceiling,
610    /// );
611    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484215");
612    /// assert_eq!(o, Greater);
613    ///
614    /// let (p, o) = Float::power_of_2_of_float_round(
615    ///     Float::from_unsigned_prec(3u32, 100).0 >> 1u32,
616    ///     Nearest,
617    /// );
618    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
619    /// assert_eq!(o, Less);
620    /// ```
621    #[inline]
622    pub fn power_of_2_of_float_round(pow: Self, rm: RoundingMode) -> (Self, Ordering) {
623        let prec = pow.significant_bits();
624        Self::power_of_2_of_float_prec_round_ref(&pow, prec, rm)
625    }
626
627    /// Computes $2^x$, where $x$ is a [`Float`], rounding the result with the specified rounding
628    /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
629    /// whether the rounded power is less than, equal to, or greater than the exact power. Although
630    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
631    /// returns `Equal`.
632    ///
633    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
634    /// description of the possible rounding modes.
635    ///
636    /// $$
637    /// f(x,m) = 2^x+\varepsilon.
638    /// $$
639    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
640    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
641    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
642    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
643    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
644    ///
645    /// If the output has a precision, it is the precision of the input.
646    ///
647    /// Special cases:
648    /// - $f(\text{NaN},m)=\text{NaN}$
649    /// - $f(\infty,m)=\infty$
650    /// - $f(-\infty,m)=0.0$
651    /// - $f(\pm0.0,m)=1.0$
652    ///
653    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on overflow
654    /// and underflow.
655    ///
656    /// If you want to specify an output precision, consider using
657    /// [`Float::power_of_2_of_float_prec_round_ref`] instead. If you know you'll be using the
658    /// `Nearest` rounding mode, consider using the [`PowerOf2`] implementation instead.
659    ///
660    /// # Worst-case complexity
661    /// $T(n) = O(n^{3/2} \log n \log\log n)$
662    ///
663    /// $M(n) = O(n \log n)$
664    ///
665    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
666    ///
667    /// # Panics
668    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
669    /// precision.
670    ///
671    /// # Examples
672    /// ```
673    /// use malachite_base::rounding_modes::RoundingMode::*;
674    /// use malachite_float::Float;
675    /// use std::cmp::Ordering::*;
676    ///
677    /// let x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
678    ///
679    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Floor);
680    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
681    /// assert_eq!(o, Less);
682    ///
683    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Ceiling);
684    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484215");
685    /// assert_eq!(o, Greater);
686    ///
687    /// let (p, o) = Float::power_of_2_of_float_round_ref(&x, Nearest);
688    /// assert_eq!(p.to_string(), "2.8284271247461900976033774484184");
689    /// assert_eq!(o, Less);
690    /// ```
691    #[inline]
692    pub fn power_of_2_of_float_round_ref(pow: &Self, rm: RoundingMode) -> (Self, Ordering) {
693        let prec = pow.significant_bits();
694        Self::power_of_2_of_float_prec_round_ref(pow, prec, rm)
695    }
696
697    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result to the specified
698    /// precision and with the specified rounding mode. An [`Ordering`] is returned, indicating
699    /// whether the rounded power is less than, equal to, or greater than the exact power. Although
700    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
701    /// `NaN` it also returns `Equal`.
702    ///
703    /// See [`RoundingMode`] for a description of the possible rounding modes.
704    ///
705    /// $$
706    /// x \gets 2^x+\varepsilon.
707    /// $$
708    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
709    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
710    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$.
711    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
712    ///   2^{\lfloor\log_2 2^x\rfloor-p}$.
713    ///
714    /// If the output has a precision, it is `prec`.
715    ///
716    /// See the [`Float::power_of_2_of_float_prec_round`] documentation for information on special
717    /// cases, overflow, and underflow.
718    ///
719    /// If you know you'll be using `Nearest`, consider using
720    /// [`Float::power_of_2_of_float_prec_assign`] instead. If you know that your target precision
721    /// is the precision of the input, consider using [`Float::power_of_2_of_float_round_assign`]
722    /// instead. If both of these things are true, consider using the [`PowerOf2Assign`]
723    /// implementation instead.
724    ///
725    /// # Worst-case complexity
726    /// $T(n) = O(n^{3/2} \log n \log\log n)$
727    ///
728    /// $M(n) = O(n \log n)$
729    ///
730    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
731    ///
732    /// # Panics
733    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
734    /// with the given precision.
735    ///
736    /// # Examples
737    /// ```
738    /// use malachite_base::rounding_modes::RoundingMode::*;
739    /// use malachite_float::Float;
740    /// use std::cmp::Ordering::*;
741    ///
742    /// let mut x = Float::from(1.5);
743    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Floor), Less);
744    /// assert_eq!(x.to_string(), "2.75");
745    ///
746    /// let mut x = Float::from(1.5);
747    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Ceiling), Greater);
748    /// assert_eq!(x.to_string(), "2.88");
749    ///
750    /// let mut x = Float::from(1.5);
751    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(5, Nearest), Greater);
752    /// assert_eq!(x.to_string(), "2.88");
753    ///
754    /// let mut x = Float::from(1.5);
755    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(20, Floor), Less);
756    /// assert_eq!(x.to_string(), "2.8284264");
757    ///
758    /// let mut x = Float::from(1.5);
759    /// assert_eq!(
760    ///     x.power_of_2_of_float_prec_round_assign(20, Ceiling),
761    ///     Greater
762    /// );
763    /// assert_eq!(x.to_string(), "2.8284302");
764    ///
765    /// let mut x = Float::from(1.5);
766    /// assert_eq!(x.power_of_2_of_float_prec_round_assign(20, Nearest), Less);
767    /// assert_eq!(x.to_string(), "2.8284264");
768    /// ```
769    #[inline]
770    pub fn power_of_2_of_float_prec_round_assign(
771        &mut self,
772        prec: u64,
773        rm: RoundingMode,
774    ) -> Ordering {
775        let (result, o) = Self::power_of_2_of_float_prec_round_ref(self, prec, rm);
776        *self = result;
777        o
778    }
779
780    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result to the nearest value
781    /// of the specified precision. An [`Ordering`] is returned, indicating whether the rounded
782    /// power is less than, equal to, or greater than the exact power. Although `NaN`s are not
783    /// comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
784    /// returns `Equal`.
785    ///
786    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
787    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
788    /// the `Nearest` rounding mode.
789    ///
790    /// $$
791    /// x \gets 2^x+\varepsilon.
792    /// $$
793    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
794    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$.
795    ///
796    /// If the output has a precision, it is `prec`.
797    ///
798    /// See the [`Float::power_of_2_of_float_prec`] documentation for information on special cases,
799    /// overflow, and underflow.
800    ///
801    /// If you want to use a rounding mode other than `Nearest`, consider using
802    /// [`Float::power_of_2_of_float_prec_round_assign`] instead. If you know that your target
803    /// precision is the precision of the input, consider using the [`PowerOf2Assign`]
804    /// implementation instead.
805    ///
806    /// # Worst-case complexity
807    /// $T(n) = O(n^{3/2} \log n \log\log n)$
808    ///
809    /// $M(n) = O(n \log n)$
810    ///
811    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
812    ///
813    /// # Panics
814    /// Panics if `prec` is zero.
815    ///
816    /// # Examples
817    /// ```
818    /// use malachite_float::Float;
819    /// use std::cmp::Ordering::*;
820    ///
821    /// let mut x = Float::from(1.5);
822    /// assert_eq!(x.power_of_2_of_float_prec_assign(5), Greater);
823    /// assert_eq!(x.to_string(), "2.88");
824    ///
825    /// let mut x = Float::from(1.5);
826    /// assert_eq!(x.power_of_2_of_float_prec_assign(20), Less);
827    /// assert_eq!(x.to_string(), "2.8284264");
828    /// ```
829    #[inline]
830    pub fn power_of_2_of_float_prec_assign(&mut self, prec: u64) -> Ordering {
831        self.power_of_2_of_float_prec_round_assign(prec, Nearest)
832    }
833
834    /// Computes $2^x$, where $x$ is a [`Float`], in place, rounding the result with the specified
835    /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded power is less
836    /// than, equal to, or greater than the exact power. Although `NaN`s are not comparable to any
837    /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
838    ///
839    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
840    /// description of the possible rounding modes.
841    ///
842    /// $$
843    /// x \gets 2^x+\varepsilon.
844    /// $$
845    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
846    /// - If $2^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
847    ///   2^{\lfloor\log_2 2^x\rfloor-p+1}$, where $p$ is the precision of the input.
848    /// - If $2^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
849    ///   2^{\lfloor\log_2 2^x\rfloor-p}$, where $p$ is the precision of the input.
850    ///
851    /// If the output has a precision, it is the precision of the input.
852    ///
853    /// See the [`Float::power_of_2_of_float_round`] documentation for information on special cases,
854    /// overflow, and underflow.
855    ///
856    /// If you want to specify an output precision, consider using
857    /// [`Float::power_of_2_of_float_prec_round_assign`] instead. If you know you'll be using the
858    /// `Nearest` rounding mode, consider using the [`PowerOf2Assign`] implementation instead.
859    ///
860    /// # Worst-case complexity
861    /// $T(n) = O(n^{3/2} \log n \log\log n)$
862    ///
863    /// $M(n) = O(n \log n)$
864    ///
865    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
866    ///
867    /// # Panics
868    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
869    /// precision.
870    ///
871    /// # Examples
872    /// ```
873    /// use malachite_base::rounding_modes::RoundingMode::*;
874    /// use malachite_float::Float;
875    /// use std::cmp::Ordering::*;
876    ///
877    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
878    /// assert_eq!(x.power_of_2_of_float_round_assign(Floor), Less);
879    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
880    ///
881    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
882    /// assert_eq!(x.power_of_2_of_float_round_assign(Ceiling), Greater);
883    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484215");
884    ///
885    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
886    /// assert_eq!(x.power_of_2_of_float_round_assign(Nearest), Less);
887    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
888    /// ```
889    #[inline]
890    pub fn power_of_2_of_float_round_assign(&mut self, rm: RoundingMode) -> Ordering {
891        let prec = self.significant_bits();
892        self.power_of_2_of_float_prec_round_assign(prec, rm)
893    }
894
895    #[allow(clippy::needless_pass_by_value)]
896    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
897    /// and with the specified rounding mode and returning the result as a [`Float`]. The
898    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
899    /// rounded power is less than, equal to, or greater than the exact power.
900    ///
901    /// See [`RoundingMode`] for a description of the possible rounding modes.
902    ///
903    /// $$
904    /// f(x,p,m) = 2^x+\varepsilon.
905    /// $$
906    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p+1}$.
907    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$.
908    ///
909    /// These bounds do not apply when the result overflows or underflows; see below.
910    ///
911    /// The output has precision `prec`.
912    ///
913    /// Special cases:
914    /// - $f(0,p,m)=1$.
915    ///
916    /// Overflow and underflow:
917    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
918    ///   returned instead.
919    /// - 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
920    ///   returned instead.
921    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
922    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
923    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
924    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
925    ///   instead.
926    ///
927    /// If you know you'll be using `Nearest`, consider using [`Float::power_of_2_rational_prec`]
928    /// instead.
929    ///
930    /// # Worst-case complexity
931    /// $T(n) = O(n^{3/2} \log n \log\log n)$
932    ///
933    /// $M(n) = O(n \log n)$
934    ///
935    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
936    ///
937    /// # Panics
938    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
939    /// with the given precision (which is the case whenever $x$ is not an integer).
940    ///
941    /// # Examples
942    /// ```
943    /// use malachite_base::rounding_modes::RoundingMode::*;
944    /// use malachite_float::Float;
945    /// use malachite_q::Rational;
946    /// use std::cmp::Ordering::*;
947    ///
948    /// let (p, o) =
949    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
950    /// assert_eq!(p.to_string(), "1.50");
951    /// assert_eq!(o, Less);
952    ///
953    /// let (p, o) =
954    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
955    /// assert_eq!(p.to_string(), "1.56");
956    /// assert_eq!(o, Greater);
957    ///
958    /// let (p, o) =
959    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
960    /// assert_eq!(p.to_string(), "1.5157166");
961    /// assert_eq!(o, Less);
962    ///
963    /// let (p, o) =
964    ///     Float::power_of_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
965    /// assert_eq!(p.to_string(), "1.5157185");
966    /// assert_eq!(o, Greater);
967    /// ```
968    #[inline]
969    pub fn power_of_2_rational_prec_round(
970        x: Rational,
971        prec: u64,
972        rm: RoundingMode,
973    ) -> (Self, Ordering) {
974        Self::power_of_2_rational_prec_round_ref(&x, prec, rm)
975    }
976
977    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the specified precision
978    /// and with the specified rounding mode and returning the result as a [`Float`]. The
979    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
980    /// rounded power is less than, equal to, or greater than the exact power.
981    ///
982    /// See [`RoundingMode`] for a description of the possible rounding modes.
983    ///
984    /// $$
985    /// f(x,p,m) = 2^x+\varepsilon.
986    /// $$
987    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p+1}$.
988    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$.
989    ///
990    /// These bounds do not apply when the result overflows or underflows; see below.
991    ///
992    /// The output has precision `prec`.
993    ///
994    /// Special cases:
995    /// - $f(0,p,m)=1$.
996    ///
997    /// Overflow and underflow:
998    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
999    ///   returned instead.
1000    /// - 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
1001    ///   returned instead.
1002    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1003    /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1004    /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1005    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1006    ///   instead.
1007    ///
1008    /// If you know you'll be using `Nearest`, consider using
1009    /// [`Float::power_of_2_rational_prec_ref`] instead.
1010    ///
1011    /// # Worst-case complexity
1012    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1013    ///
1014    /// $M(n) = O(n \log n)$
1015    ///
1016    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1017    ///
1018    /// # Panics
1019    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1020    /// with the given precision (which is the case whenever $x$ is not an integer).
1021    ///
1022    /// # Examples
1023    /// ```
1024    /// use malachite_base::rounding_modes::RoundingMode::*;
1025    /// use malachite_float::Float;
1026    /// use malachite_q::Rational;
1027    /// use std::cmp::Ordering::*;
1028    ///
1029    /// let (p, o) =
1030    ///     Float::power_of_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1031    /// assert_eq!(p.to_string(), "1.50");
1032    /// assert_eq!(o, Less);
1033    ///
1034    /// let (p, o) = Float::power_of_2_rational_prec_round_ref(
1035    ///     &Rational::from_unsigneds(3u8, 5),
1036    ///     5,
1037    ///     Ceiling,
1038    /// );
1039    /// assert_eq!(p.to_string(), "1.56");
1040    /// assert_eq!(o, Greater);
1041    ///
1042    /// let (p, o) =
1043    ///     Float::power_of_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1044    /// assert_eq!(p.to_string(), "1.5157166");
1045    /// assert_eq!(o, Less);
1046    ///
1047    /// let (p, o) = Float::power_of_2_rational_prec_round_ref(
1048    ///     &Rational::from_unsigneds(3u8, 5),
1049    ///     20,
1050    ///     Ceiling,
1051    /// );
1052    /// assert_eq!(p.to_string(), "1.5157185");
1053    /// assert_eq!(o, Greater);
1054    /// ```
1055    pub fn power_of_2_rational_prec_round_ref(
1056        x: &Rational,
1057        prec: u64,
1058        rm: RoundingMode,
1059    ) -> (Self, Ordering) {
1060        assert_ne!(prec, 0);
1061        // If x is an integer, 2^x is exactly a power of 2 (this includes 2^0 = 1). Handle it
1062        // directly: the Ziv loop in the helper never converges on an exactly-representable result.
1063        if let Ok(n) = Integer::try_from(x) {
1064            return if let Ok(pow) = i64::try_from(&n) {
1065                // `power_of_2_prec_round` handles its own overflow and underflow.
1066                Self::power_of_2_prec_round(pow, prec, rm)
1067            } else if x.sign() == Greater {
1068                // x is too large to fit in an i64, so 2^x overflows.
1069                exp_overflow(prec, rm)
1070            } else {
1071                exp_underflow(prec, rm)
1072            };
1073        }
1074        power_of_2_rational_helper(x, prec, rm)
1075    }
1076
1077    #[allow(clippy::needless_pass_by_value)]
1078    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of the
1079    /// specified precision and returning the result as a [`Float`]. The [`Rational`] is taken by
1080    /// value. An [`Ordering`] is also returned, indicating whether the rounded power is less than,
1081    /// equal to, or greater than the exact power.
1082    ///
1083    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1084    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1085    /// the `Nearest` rounding mode.
1086    ///
1087    /// $$
1088    /// f(x,p) = 2^x+\varepsilon,
1089    /// $$
1090    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$ (unless the result overflows or
1091    /// underflows; see below).
1092    ///
1093    /// The output has precision `prec`.
1094    ///
1095    /// Special cases:
1096    /// - $f(0,p)=1$.
1097    ///
1098    /// Overflow and underflow:
1099    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1100    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1101    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1102    ///
1103    /// If you want to use a rounding mode other than `Nearest`, consider using
1104    /// [`Float::power_of_2_rational_prec_round`] instead.
1105    ///
1106    /// # Worst-case complexity
1107    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1108    ///
1109    /// $M(n) = O(n \log n)$
1110    ///
1111    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1112    ///
1113    /// # Panics
1114    /// Panics if `prec` is zero.
1115    ///
1116    /// # Examples
1117    /// ```
1118    /// use malachite_float::Float;
1119    /// use malachite_q::Rational;
1120    /// use std::cmp::Ordering::*;
1121    ///
1122    /// let (p, o) = Float::power_of_2_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1123    /// assert_eq!(p.to_string(), "1.50");
1124    /// assert_eq!(o, Less);
1125    ///
1126    /// let (p, o) = Float::power_of_2_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1127    /// assert_eq!(p.to_string(), "1.5157166");
1128    /// assert_eq!(o, Less);
1129    ///
1130    /// let (p, o) = Float::power_of_2_rational_prec(Rational::from(0), 10);
1131    /// assert_eq!(p.to_string(), "1.0000");
1132    /// assert_eq!(o, Equal);
1133    /// ```
1134    #[inline]
1135    pub fn power_of_2_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1136        Self::power_of_2_rational_prec_round_ref(&x, prec, Nearest)
1137    }
1138
1139    /// Computes $2^x$, where $x$ is a [`Rational`], rounding the result to the nearest value of the
1140    /// specified precision and returning the result as a [`Float`]. The [`Rational`] is taken by
1141    /// reference. An [`Ordering`] is also returned, indicating whether the rounded power is less
1142    /// than, equal to, or greater than the exact power.
1143    ///
1144    /// If the power is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1145    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1146    /// the `Nearest` rounding mode.
1147    ///
1148    /// $$
1149    /// f(x,p) = 2^x+\varepsilon,
1150    /// $$
1151    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 2^x\rfloor-p}$ (unless the result overflows or
1152    /// underflows; see below).
1153    ///
1154    /// The output has precision `prec`.
1155    ///
1156    /// Special cases:
1157    /// - $f(0,p)=1$.
1158    ///
1159    /// Overflow and underflow:
1160    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1161    /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1162    /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1163    ///
1164    /// If you want to use a rounding mode other than `Nearest`, consider using
1165    /// [`Float::power_of_2_rational_prec_round_ref`] instead.
1166    ///
1167    /// # Worst-case complexity
1168    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1169    ///
1170    /// $M(n) = O(n \log n)$
1171    ///
1172    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1173    ///
1174    /// # Panics
1175    /// Panics if `prec` is zero.
1176    ///
1177    /// # Examples
1178    /// ```
1179    /// use malachite_float::Float;
1180    /// use malachite_q::Rational;
1181    /// use std::cmp::Ordering::*;
1182    ///
1183    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1184    /// assert_eq!(p.to_string(), "1.50");
1185    /// assert_eq!(o, Less);
1186    ///
1187    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1188    /// assert_eq!(p.to_string(), "1.5157166");
1189    /// assert_eq!(o, Less);
1190    ///
1191    /// let (p, o) = Float::power_of_2_rational_prec_ref(&Rational::from(0), 10);
1192    /// assert_eq!(p.to_string(), "1.0000");
1193    /// assert_eq!(o, Equal);
1194    /// ```
1195    #[inline]
1196    pub fn power_of_2_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1197        Self::power_of_2_rational_prec_round_ref(x, prec, Nearest)
1198    }
1199}
1200
1201impl PowerOf2<Self> for Float {
1202    /// Computes $2^x$, where $x$ is a [`Float`], taking it by value.
1203    ///
1204    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1205    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1206    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1207    ///
1208    /// $$
1209    /// f(x) = 2^x+\varepsilon.
1210    /// $$
1211    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1212    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1213    ///   where $p$ is the precision of the input.
1214    ///
1215    /// Special cases:
1216    /// - $f(\text{NaN})=\text{NaN}$
1217    /// - $f(\infty)=\infty$
1218    /// - $f(-\infty)=0.0$
1219    /// - $f(\pm0.0)=1.0$
1220    ///
1221    /// See the [`Float::power_of_2_of_float_round`] documentation for information on overflow and
1222    /// underflow.
1223    ///
1224    /// If you want to use a rounding mode other than `Nearest`, consider using
1225    /// [`Float::power_of_2_of_float_round`] instead. If you want to specify the output precision,
1226    /// consider using [`Float::power_of_2_of_float_prec`]. If you want both of these things,
1227    /// consider using [`Float::power_of_2_of_float_prec_round`].
1228    ///
1229    /// # Worst-case complexity
1230    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1231    ///
1232    /// $M(n) = O(n \log n)$
1233    ///
1234    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1235    ///
1236    /// # Examples
1237    /// ```
1238    /// use malachite_base::num::arithmetic::traits::PowerOf2;
1239    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1240    /// use malachite_float::Float;
1241    ///
1242    /// assert!(Float::power_of_2(Float::NAN).is_nan());
1243    /// assert_eq!(Float::power_of_2(Float::INFINITY), Float::INFINITY);
1244    /// assert_eq!(Float::power_of_2(Float::NEGATIVE_INFINITY), Float::ZERO);
1245    /// assert_eq!(
1246    ///     Float::power_of_2(Float::from_unsigned_prec(3u32, 100).0 >> 1u32).to_string(),
1247    ///     "2.8284271247461900976033774484184"
1248    /// );
1249    /// ```
1250    #[inline]
1251    fn power_of_2(pow: Self) -> Self {
1252        Self::power_of_2_of_float_round(pow, Nearest).0
1253    }
1254}
1255
1256impl PowerOf2<&Self> for Float {
1257    /// Computes $2^x$, where $x$ is a [`Float`], taking it by reference.
1258    ///
1259    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1260    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1261    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1262    ///
1263    /// $$
1264    /// f(x) = 2^x+\varepsilon.
1265    /// $$
1266    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1267    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1268    ///   where $p$ is the precision of the input.
1269    ///
1270    /// Special cases:
1271    /// - $f(\text{NaN})=\text{NaN}$
1272    /// - $f(\infty)=\infty$
1273    /// - $f(-\infty)=0.0$
1274    /// - $f(\pm0.0)=1.0$
1275    ///
1276    /// See the [`Float::power_of_2_of_float_round`] documentation for information on overflow and
1277    /// underflow.
1278    ///
1279    /// If you want to use a rounding mode other than `Nearest`, consider using
1280    /// [`Float::power_of_2_of_float_round_ref`] instead. If you want to specify the output
1281    /// precision, consider using [`Float::power_of_2_of_float_prec_ref`]. If you want both of these
1282    /// things, consider using [`Float::power_of_2_of_float_prec_round_ref`].
1283    ///
1284    /// # Worst-case complexity
1285    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1286    ///
1287    /// $M(n) = O(n \log n)$
1288    ///
1289    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1290    ///
1291    /// # Examples
1292    /// ```
1293    /// use malachite_base::num::arithmetic::traits::PowerOf2;
1294    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1295    /// use malachite_float::Float;
1296    ///
1297    /// assert!(Float::power_of_2(&Float::NAN).is_nan());
1298    /// assert_eq!(Float::power_of_2(&Float::INFINITY), Float::INFINITY);
1299    /// assert_eq!(Float::power_of_2(&Float::NEGATIVE_INFINITY), Float::ZERO);
1300    /// assert_eq!(
1301    ///     Float::power_of_2(&(Float::from_unsigned_prec(3u32, 100).0 >> 1u32)).to_string(),
1302    ///     "2.8284271247461900976033774484184"
1303    /// );
1304    /// ```
1305    #[inline]
1306    fn power_of_2(pow: &Self) -> Self {
1307        Self::power_of_2_of_float_round_ref(pow, Nearest).0
1308    }
1309}
1310
1311impl PowerOf2Assign for Float {
1312    /// Computes $2^x$, where $x$ is a [`Float`], in place.
1313    ///
1314    /// If the output has a precision, it is the precision of the input. If the power is equidistant
1315    /// from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in its binary
1316    /// expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding mode.
1317    ///
1318    /// $$
1319    /// x \gets 2^x+\varepsilon.
1320    /// $$
1321    /// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1322    /// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$,
1323    ///   where $p$ is the precision of the input.
1324    ///
1325    /// See the [`Float::power_of_2_of_float_round`] documentation for information on special cases,
1326    /// overflow, and underflow.
1327    ///
1328    /// If you want to use a rounding mode other than `Nearest`, consider using
1329    /// [`Float::power_of_2_of_float_round_assign`] instead. If you want to specify the output
1330    /// precision, consider using [`Float::power_of_2_of_float_prec_assign`]. If you want both of
1331    /// these things, consider using [`Float::power_of_2_of_float_prec_round_assign`].
1332    ///
1333    /// # Worst-case complexity
1334    /// $T(n) = O(n^{3/2} \log n \log\log n)$
1335    ///
1336    /// $M(n) = O(n \log n)$
1337    ///
1338    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1339    ///
1340    /// # Examples
1341    /// ```
1342    /// use malachite_base::num::arithmetic::traits::PowerOf2Assign;
1343    /// use malachite_float::Float;
1344    ///
1345    /// let mut x = Float::from_unsigned_prec(3u32, 100).0 >> 1u32;
1346    /// x.power_of_2_assign();
1347    /// assert_eq!(x.to_string(), "2.8284271247461900976033774484184");
1348    /// ```
1349    #[inline]
1350    fn power_of_2_assign(&mut self) {
1351        self.power_of_2_of_float_round_assign(Nearest);
1352    }
1353}
1354
1355/// Computes $2^x$, where $x$ is a primitive float, returning the result as a primitive float of the
1356/// same type. Using this function is more accurate than using `x.exp2()` or the `exp2` function
1357/// provided by `libm`.
1358///
1359/// $$
1360/// f(x) = 2^x+\varepsilon.
1361/// $$
1362/// - If $2^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1363/// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$, where
1364///   $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1365///   [`f64`], but less if the output is subnormal).
1366///
1367/// Special cases:
1368/// - $f(\text{NaN})=\text{NaN}$
1369/// - $f(\infty)=\infty$
1370/// - $f(-\infty)=0.0$
1371/// - $f(\pm0.0)=1.0$
1372///
1373/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1374/// `x` gives `0.0`.
1375///
1376/// # Worst-case complexity
1377/// Constant time and additional memory.
1378///
1379/// # Examples
1380/// ```
1381/// use malachite_base::num::basic::traits::NegativeInfinity;
1382/// use malachite_base::num::float::NiceFloat;
1383/// use malachite_float::float::arithmetic::power_of_2_of_float::primitive_float_power_of_2;
1384///
1385/// assert!(primitive_float_power_of_2(f32::NAN).is_nan());
1386/// assert_eq!(
1387///     NiceFloat(primitive_float_power_of_2(f32::INFINITY)),
1388///     NiceFloat(f32::INFINITY)
1389/// );
1390/// assert_eq!(
1391///     NiceFloat(primitive_float_power_of_2(f32::NEGATIVE_INFINITY)),
1392///     NiceFloat(0.0)
1393/// );
1394/// assert_eq!(
1395///     NiceFloat(primitive_float_power_of_2(0.0f32)),
1396///     NiceFloat(1.0)
1397/// );
1398/// assert_eq!(
1399///     NiceFloat(primitive_float_power_of_2(1.0f32)),
1400///     NiceFloat(2.0)
1401/// );
1402/// assert_eq!(
1403///     NiceFloat(primitive_float_power_of_2(0.5f32)),
1404///     NiceFloat(1.4142135)
1405/// );
1406/// ```
1407#[inline]
1408#[allow(clippy::type_repetition_in_bounds)]
1409pub fn primitive_float_power_of_2<T: PrimitiveFloat>(x: T) -> T
1410where
1411    Float: From<T> + PartialOrd<T>,
1412    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1413{
1414    emulate_float_to_float_fn(Float::power_of_2_of_float_prec, x)
1415}
1416
1417/// Computes $2^x$, where $x$ is a [`Rational`], returning the result as a primitive float.
1418///
1419/// $$
1420/// f(x) = 2^x+\varepsilon.
1421/// $$
1422/// - If $2^x$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
1423/// - If $2^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 2^x\rfloor-p}$, where
1424///   $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1425///   [`f64`], but less if the output is subnormal).
1426///
1427/// Special cases:
1428/// - $f(0)=1$
1429///
1430/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1431/// `x` gives `0.0`.
1432///
1433/// # Worst-case complexity
1434/// Constant time and additional memory.
1435///
1436/// # Examples
1437/// ```
1438/// use malachite_base::num::basic::traits::Zero;
1439/// use malachite_base::num::float::NiceFloat;
1440/// use malachite_float::float::arithmetic::power_of_2_of_float::*;
1441/// use malachite_q::Rational;
1442///
1443/// assert_eq!(
1444///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::ZERO)),
1445///     NiceFloat(1.0)
1446/// );
1447/// assert_eq!(
1448///     NiceFloat(primitive_float_power_of_2_rational::<f64>(
1449///         &Rational::from_unsigneds(1u8, 3)
1450///     )),
1451///     NiceFloat(1.2599210498948732)
1452/// );
1453/// assert_eq!(
1454///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::from(
1455///         10000
1456///     ))),
1457///     NiceFloat(f64::INFINITY)
1458/// );
1459/// assert_eq!(
1460///     NiceFloat(primitive_float_power_of_2_rational::<f64>(&Rational::from(
1461///         -10000
1462///     ))),
1463///     NiceFloat(0.0)
1464/// );
1465/// ```
1466#[inline]
1467#[allow(clippy::type_repetition_in_bounds)]
1468pub fn primitive_float_power_of_2_rational<T: PrimitiveFloat>(x: &Rational) -> T
1469where
1470    Float: PartialOrd<T>,
1471    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1472{
1473    emulate_rational_to_float_fn(Float::power_of_2_rational_prec_ref, x)
1474}