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}