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