Skip to main content

malachite_float/arithmetic/
log_base_power_of_2.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
10use crate::{
11    Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, float_either_zero,
12    float_infinity, float_nan, float_negative_infinity,
13};
14use core::cmp::Ordering::{self, *};
15use malachite_base::num::arithmetic::traits::{
16    CeilingLogBase2, CheckedLogBase2, IsPowerOf2, LogBasePowerOf2, LogBasePowerOf2Assign, Sign,
17};
18use malachite_base::num::basic::floats::PrimitiveFloat;
19use malachite_base::num::basic::integers::PrimitiveInt;
20use malachite_base::num::basic::traits::Zero as ZeroTrait;
21use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
22use malachite_base::num::logic::traits::SignificantBits;
23use malachite_base::rounding_modes::RoundingMode::{self, *};
24use malachite_nz::natural::arithmetic::float_extras::float_can_round;
25use malachite_nz::platform::Limb;
26use malachite_q::Rational;
27
28// The computation of log_base_power_of_2(x, pow) is done by log_{2^pow}(x) = log_2(x) / pow, where
29// the input is finite, nonzero, and positive.
30fn log_base_power_of_2_prec_round_normal(
31    x: &Float,
32    pow: i64,
33    prec: u64,
34    rm: RoundingMode,
35) -> (Float, Ordering) {
36    // If x is 1, the result is 0.
37    if *x == 1u32 {
38        return (Float::ZERO, Equal);
39    }
40    // If x is 2^m, then log_2(x) = m and the result is the rational m / pow (exact when
41    // representable at the target precision).
42    if x.is_power_of_2() {
43        let m = i64::from(x.get_exponent().unwrap()) - 1;
44        return Float::from(m).div_prec_round(Float::from(pow), prec, rm);
45    }
46    // The result is never exactly representable otherwise.
47    assert_ne!(rm, Exact, "Inexact log_base_power_of_2");
48    let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
49    let mut increment = Limb::WIDTH;
50    loop {
51        // log_2(x) / pow, with two correctly-rounded operations: log_base_2 (at most 1/2 ulp) and
52        // division by the exact integer pow (at most 1/2 ulp). The relative error is thus below
53        // 2^(1 - working_prec), so working_prec - 2 correct bits suffice for rounding.
54        let t = x
55            .log_base_2_prec_ref(working_prec)
56            .0
57            .div_prec(Float::from(pow), working_prec)
58            .0;
59        if float_can_round(t.significand_ref().unwrap(), working_prec - 2, prec, rm) {
60            return Float::from_float_prec_round(t, prec, rm);
61        }
62        // Increase the precision.
63        working_prec += increment;
64        increment = working_prec >> 1;
65    }
66}
67
68// The computation of log_base_power_of_2_rational(x, pow) is done by log_{2^pow}(x) = log_2(x) /
69// pow, where the input is a positive [`Rational`] that is not a power of 2. The base-2 logarithm of
70// a [`Rational`] (computed by `log_base_2_rational_prec_ref`) already handles inputs that are
71// extremely close to a power of 2 without needing extra precision, so a simple Ziv loop dividing by
72// the exact integer pow suffices here.
73fn log_base_power_of_2_rational_prec_round_helper(
74    x: &Rational,
75    pow: i64,
76    prec: u64,
77    rm: RoundingMode,
78) -> (Float, Ordering) {
79    let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
80    let mut increment = Limb::WIDTH;
81    loop {
82        // log_2(x) / pow, with two correctly-rounded operations: log_base_2_rational (at most 1/2
83        // ulp) and division by the exact integer pow (at most 1/2 ulp). The relative error is thus
84        // below 2^(1 - working_prec), so working_prec - 2 correct bits suffice for rounding.
85        let t = Float::log_base_2_rational_prec_ref(x, working_prec)
86            .0
87            .div_prec(Float::from(pow), working_prec)
88            .0;
89        if float_can_round(t.significand_ref().unwrap(), working_prec - 2, prec, rm) {
90            return Float::from_float_prec_round(t, prec, rm);
91        }
92        // Increase the precision.
93        working_prec += increment;
94        increment = working_prec >> 1;
95    }
96}
97
98impl Float {
99    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
100    /// integer $k$, rounding the result to the specified precision and with the specified rounding
101    /// mode. The base's exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by
102    /// value. An [`Ordering`] is also returned, indicating whether the rounded value is less than,
103    /// equal to, or greater than the exact value. Although `NaN`s are not comparable to any
104    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
105    ///
106    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
107    ///
108    /// See [`RoundingMode`] for a description of the possible rounding modes.
109    ///
110    /// $$
111    /// f(x,k,p,m) = \log_{2^k} x+\varepsilon.
112    /// $$
113    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
114    ///   be 0.
115    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
116    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$.
117    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
118    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$.
119    ///
120    /// If the output has a precision, it is `prec`.
121    ///
122    /// Special cases:
123    /// - $f(\text{NaN},k,p,m)=\text{NaN}$
124    /// - $f(\infty,k,p,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
125    /// - $f(-\infty,k,p,m)=\text{NaN}$
126    /// - $f(\pm0.0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
127    /// - $f(1.0,k,p,m)=0.0$, and the result is exact
128    /// - $f(2^m,k,p,m')=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
129    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
130    ///   is not)
131    /// - $f(x,k,p,m)=\text{NaN}$ for $x<0$
132    ///
133    /// Neither overflow nor underflow is possible.
134    ///
135    /// If you know you'll be using `Nearest`, consider using [`Float::log_base_power_of_2_prec`]
136    /// instead. If you know that your target precision is the precision of the input, consider
137    /// using [`Float::log_base_power_of_2_round`] instead. If both of these things are true,
138    /// consider using [`Float::log_base_power_of_2`] instead.
139    ///
140    /// # Worst-case complexity
141    /// $T(n) = O(n (\log n)^2 \log\log n)$
142    ///
143    /// $M(n) = O(n (\log n)^2)$
144    ///
145    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
146    ///
147    /// # Panics
148    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
149    /// is `Exact` but the result cannot be represented exactly with the given precision. (The
150    /// result is exactly representable if and only if the input is `NaN`, infinite, zero, equal to
151    /// 1, or a power of 2 whose base-$2^k$ logarithm is representable with the given precision.)
152    ///
153    /// # Examples
154    /// ```
155    /// use malachite_base::rounding_modes::RoundingMode::*;
156    /// use malachite_float::Float;
157    /// use std::cmp::Ordering::*;
158    ///
159    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
160    ///     .0
161    ///     .log_base_power_of_2_prec_round(2, 5, Floor);
162    /// assert_eq!(log.to_string(), "1.62");
163    /// assert_eq!(o, Less);
164    ///
165    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
166    ///     .0
167    ///     .log_base_power_of_2_prec_round(2, 5, Ceiling);
168    /// assert_eq!(log.to_string(), "1.7");
169    /// assert_eq!(o, Greater);
170    ///
171    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
172    ///     .0
173    ///     .log_base_power_of_2_prec_round(2, 5, Nearest);
174    /// assert_eq!(log.to_string(), "1.7");
175    /// assert_eq!(o, Greater);
176    ///
177    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
178    ///     .0
179    ///     .log_base_power_of_2_prec_round(3, 20, Floor);
180    /// assert_eq!(log.to_string(), "1.107309");
181    /// assert_eq!(o, Less);
182    ///
183    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
184    ///     .0
185    ///     .log_base_power_of_2_prec_round(3, 20, Ceiling);
186    /// assert_eq!(log.to_string(), "1.107311");
187    /// assert_eq!(o, Greater);
188    ///
189    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
190    ///     .0
191    ///     .log_base_power_of_2_prec_round(3, 20, Nearest);
192    /// assert_eq!(log.to_string(), "1.107309");
193    /// assert_eq!(o, Less);
194    ///
195    /// // log_4(8) = 3/2, exactly representable
196    /// let (log, o) = Float::from(8u32).log_base_power_of_2_prec_round(2, 10, Nearest);
197    /// assert_eq!(log.to_string(), "1.5");
198    /// assert_eq!(o, Equal);
199    /// ```
200    #[inline]
201    pub fn log_base_power_of_2_prec_round(
202        self,
203        pow: i64,
204        prec: u64,
205        rm: RoundingMode,
206    ) -> (Self, Ordering) {
207        assert_ne!(prec, 0);
208        assert_ne!(pow, 0, "Cannot take base-1 logarithm");
209        match self {
210            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
211                (float_nan!(), Equal)
212            }
213            float_either_zero!() => (
214                if pow > 0 {
215                    float_negative_infinity!()
216                } else {
217                    float_infinity!()
218                },
219                Equal,
220            ),
221            float_infinity!() => (
222                if pow > 0 {
223                    float_infinity!()
224                } else {
225                    float_negative_infinity!()
226                },
227                Equal,
228            ),
229            _ => log_base_power_of_2_prec_round_normal(&self, pow, prec, rm),
230        }
231    }
232
233    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
234    /// integer $k$, rounding the result to the specified precision and with the specified rounding
235    /// mode. The base's exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by
236    /// reference. An [`Ordering`] is also returned, indicating whether the rounded value is less
237    /// than, equal to, or greater than the exact value. Although `NaN`s are not comparable to any
238    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
239    ///
240    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
241    ///
242    /// See [`RoundingMode`] for a description of the possible rounding modes.
243    ///
244    /// $$
245    /// f(x,k,p,m) = \log_{2^k} x+\varepsilon.
246    /// $$
247    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
248    ///   be 0.
249    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
250    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$.
251    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
252    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$.
253    ///
254    /// If the output has a precision, it is `prec`.
255    ///
256    /// Special cases:
257    /// - $f(\text{NaN},k,p,m)=\text{NaN}$
258    /// - $f(\infty,k,p,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
259    /// - $f(-\infty,k,p,m)=\text{NaN}$
260    /// - $f(\pm0.0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
261    /// - $f(1.0,k,p,m)=0.0$, and the result is exact
262    /// - $f(2^m,k,p,m')=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
263    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
264    ///   is not)
265    /// - $f(x,k,p,m)=\text{NaN}$ for $x<0$
266    ///
267    /// Neither overflow nor underflow is possible.
268    ///
269    /// If you know you'll be using `Nearest`, consider using
270    /// [`Float::log_base_power_of_2_prec_ref`] instead. If you know that your target precision is
271    /// the precision of the input, consider using [`Float::log_base_power_of_2_round_ref`] instead.
272    /// If both of these things are true, consider using `(&Float).log_base_power_of_2()` instead.
273    ///
274    /// # Worst-case complexity
275    /// $T(n) = O(n (\log n)^2 \log\log n)$
276    ///
277    /// $M(n) = O(n (\log n)^2)$
278    ///
279    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
280    ///
281    /// # Panics
282    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
283    /// is `Exact` but the result cannot be represented exactly with the given precision. (The
284    /// result is exactly representable if and only if the input is `NaN`, infinite, zero, equal to
285    /// 1, or a power of 2 whose base-$2^k$ logarithm is representable with the given precision.)
286    ///
287    /// # Examples
288    /// ```
289    /// use malachite_base::rounding_modes::RoundingMode::*;
290    /// use malachite_float::Float;
291    /// use std::cmp::Ordering::*;
292    ///
293    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
294    ///     .0
295    ///     .log_base_power_of_2_prec_round_ref(2, 5, Floor);
296    /// assert_eq!(log.to_string(), "1.62");
297    /// assert_eq!(o, Less);
298    ///
299    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
300    ///     .0
301    ///     .log_base_power_of_2_prec_round_ref(2, 5, Ceiling);
302    /// assert_eq!(log.to_string(), "1.7");
303    /// assert_eq!(o, Greater);
304    ///
305    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
306    ///     .0
307    ///     .log_base_power_of_2_prec_round_ref(2, 5, Nearest);
308    /// assert_eq!(log.to_string(), "1.7");
309    /// assert_eq!(o, Greater);
310    ///
311    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
312    ///     .0
313    ///     .log_base_power_of_2_prec_round_ref(3, 20, Floor);
314    /// assert_eq!(log.to_string(), "1.107309");
315    /// assert_eq!(o, Less);
316    ///
317    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
318    ///     .0
319    ///     .log_base_power_of_2_prec_round_ref(3, 20, Ceiling);
320    /// assert_eq!(log.to_string(), "1.107311");
321    /// assert_eq!(o, Greater);
322    ///
323    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
324    ///     .0
325    ///     .log_base_power_of_2_prec_round_ref(3, 20, Nearest);
326    /// assert_eq!(log.to_string(), "1.107309");
327    /// assert_eq!(o, Less);
328    ///
329    /// // log_4(8) = 3/2, exactly representable
330    /// let (log, o) = Float::from(8u32).log_base_power_of_2_prec_round_ref(2, 10, Nearest);
331    /// assert_eq!(log.to_string(), "1.5");
332    /// assert_eq!(o, Equal);
333    /// ```
334    #[inline]
335    pub fn log_base_power_of_2_prec_round_ref(
336        &self,
337        pow: i64,
338        prec: u64,
339        rm: RoundingMode,
340    ) -> (Self, Ordering) {
341        assert_ne!(prec, 0);
342        assert_ne!(pow, 0, "Cannot take base-1 logarithm");
343        match self {
344            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
345                (float_nan!(), Equal)
346            }
347            float_either_zero!() => (
348                if pow > 0 {
349                    float_negative_infinity!()
350                } else {
351                    float_infinity!()
352                },
353                Equal,
354            ),
355            float_infinity!() => (
356                if pow > 0 {
357                    float_infinity!()
358                } else {
359                    float_negative_infinity!()
360                },
361                Equal,
362            ),
363            _ => log_base_power_of_2_prec_round_normal(self, pow, prec, rm),
364        }
365    }
366
367    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
368    /// integer $k$, rounding the result to the nearest value of the specified precision. The base's
369    /// exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by value. An
370    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
371    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
372    /// whenever this function returns a `NaN` it also returns `Equal`.
373    ///
374    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
375    ///
376    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
377    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
378    /// description of the `Nearest` rounding mode.
379    ///
380    /// $$
381    /// f(x,k,p) = \log_{2^k} x+\varepsilon.
382    /// $$
383    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
384    ///   be 0.
385    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
386    ///   |\log_{2^k} x|\rfloor-p}$.
387    ///
388    /// If the output has a precision, it is `prec`.
389    ///
390    /// Special cases:
391    /// - $f(\text{NaN},k,p)=\text{NaN}$
392    /// - $f(\infty,k,p)=\infty$ if $k>0$, and $-\infty$ if $k<0$
393    /// - $f(-\infty,k,p)=\text{NaN}$
394    /// - $f(\pm0.0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
395    /// - $f(1.0,k,p)=0.0$, and the result is exact
396    /// - $f(2^m,k,p)=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
397    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
398    ///   is not)
399    /// - $f(x,k,p)=\text{NaN}$ for $x<0$
400    ///
401    /// Neither overflow nor underflow is possible.
402    ///
403    /// If you want to use a rounding mode other than `Nearest`, consider using
404    /// [`Float::log_base_power_of_2_prec_round`] instead. If you know that your target precision is
405    /// the precision of the input, consider using [`Float::log_base_power_of_2`] instead.
406    ///
407    /// # Worst-case complexity
408    /// $T(n) = O(n (\log n)^2 \log\log n)$
409    ///
410    /// $M(n) = O(n (\log n)^2)$
411    ///
412    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
413    ///
414    /// # Panics
415    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
416    ///
417    /// # Examples
418    /// ```
419    /// use malachite_float::Float;
420    /// use std::cmp::Ordering::*;
421    ///
422    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
423    ///     .0
424    ///     .log_base_power_of_2_prec(2, 5);
425    /// assert_eq!(log.to_string(), "1.7");
426    /// assert_eq!(o, Greater);
427    ///
428    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
429    ///     .0
430    ///     .log_base_power_of_2_prec(3, 20);
431    /// assert_eq!(log.to_string(), "1.107309");
432    /// assert_eq!(o, Less);
433    /// ```
434    #[inline]
435    pub fn log_base_power_of_2_prec(self, pow: i64, prec: u64) -> (Self, Ordering) {
436        self.log_base_power_of_2_prec_round(pow, prec, Nearest)
437    }
438
439    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
440    /// integer $k$, rounding the result to the nearest value of the specified precision. The base's
441    /// exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by reference. An
442    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
443    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
444    /// whenever this function returns a `NaN` it also returns `Equal`.
445    ///
446    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
447    ///
448    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
449    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
450    /// description of the `Nearest` rounding mode.
451    ///
452    /// $$
453    /// f(x,k,p) = \log_{2^k} x+\varepsilon.
454    /// $$
455    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
456    ///   be 0.
457    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
458    ///   |\log_{2^k} x|\rfloor-p}$.
459    ///
460    /// If the output has a precision, it is `prec`.
461    ///
462    /// Special cases:
463    /// - $f(\text{NaN},k,p)=\text{NaN}$
464    /// - $f(\infty,k,p)=\infty$ if $k>0$, and $-\infty$ if $k<0$
465    /// - $f(-\infty,k,p)=\text{NaN}$
466    /// - $f(\pm0.0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
467    /// - $f(1.0,k,p)=0.0$, and the result is exact
468    /// - $f(2^m,k,p)=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
469    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
470    ///   is not)
471    /// - $f(x,k,p)=\text{NaN}$ for $x<0$
472    ///
473    /// Neither overflow nor underflow is possible.
474    ///
475    /// If you want to use a rounding mode other than `Nearest`, consider using
476    /// [`Float::log_base_power_of_2_prec_round_ref`] instead. If you know that your target
477    /// precision is the precision of the input, consider using `(&Float).log_base_power_of_2()`
478    /// instead.
479    ///
480    /// # Worst-case complexity
481    /// $T(n) = O(n (\log n)^2 \log\log n)$
482    ///
483    /// $M(n) = O(n (\log n)^2)$
484    ///
485    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
486    ///
487    /// # Panics
488    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
489    ///
490    /// # Examples
491    /// ```
492    /// use malachite_float::Float;
493    /// use std::cmp::Ordering::*;
494    ///
495    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
496    ///     .0
497    ///     .log_base_power_of_2_prec_ref(2, 5);
498    /// assert_eq!(log.to_string(), "1.7");
499    /// assert_eq!(o, Greater);
500    ///
501    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
502    ///     .0
503    ///     .log_base_power_of_2_prec_ref(3, 20);
504    /// assert_eq!(log.to_string(), "1.107309");
505    /// assert_eq!(o, Less);
506    /// ```
507    #[inline]
508    pub fn log_base_power_of_2_prec_ref(&self, pow: i64, prec: u64) -> (Self, Ordering) {
509        self.log_base_power_of_2_prec_round_ref(pow, prec, Nearest)
510    }
511
512    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
513    /// integer $k$, rounding the result with the specified rounding mode. The base's exponent $k$
514    /// is `pow`, which may be negative. The [`Float`] is taken by value. An [`Ordering`] is also
515    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
516    /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
517    /// returns a `NaN` it also returns `Equal`.
518    ///
519    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
520    ///
521    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
522    /// description of the possible rounding modes.
523    ///
524    /// $$
525    /// f(x,k,m) = \log_{2^k} x+\varepsilon.
526    /// $$
527    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
528    ///   be 0.
529    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
530    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$, where $p$ is the precision of the input.
531    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
532    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
533    ///
534    /// If the output has a precision, it is the precision of the input.
535    ///
536    /// Special cases:
537    /// - $f(\text{NaN},k,m)=\text{NaN}$
538    /// - $f(\infty,k,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
539    /// - $f(-\infty,k,m)=\text{NaN}$
540    /// - $f(\pm0.0,k,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
541    /// - $f(1.0,k,m)=0.0$, and the result is exact
542    /// - $f(2^m,k,m')=m/k$, rounded to the precision of the input; the result is exact if and only
543    ///   if $m/k$ is representable with that precision (for example $\log_4 8=3/2$ is exact, but
544    ///   $\log_8 4=2/3$ is not)
545    /// - $f(x,k,m)=\text{NaN}$ for $x<0$
546    ///
547    /// Neither overflow nor underflow is possible.
548    ///
549    /// If you want to specify an output precision, consider using
550    /// [`Float::log_base_power_of_2_prec_round`] instead. If you know you'll be using the `Nearest`
551    /// rounding mode, consider using [`Float::log_base_power_of_2`] instead.
552    ///
553    /// # Worst-case complexity
554    /// $T(n) = O(n (\log n)^2 \log\log n)$
555    ///
556    /// $M(n) = O(n (\log n)^2)$
557    ///
558    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
559    ///
560    /// # Panics
561    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
562    /// result cannot be represented exactly with the input precision. (The result is exactly
563    /// representable if and only if the input is `NaN`, infinite, zero, equal to 1, or a power of 2
564    /// whose base-$2^k$ logarithm is representable with the input precision.)
565    ///
566    /// # Examples
567    /// ```
568    /// use malachite_base::rounding_modes::RoundingMode::*;
569    /// use malachite_float::Float;
570    /// use std::cmp::Ordering::*;
571    ///
572    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
573    ///     .0
574    ///     .log_base_power_of_2_round(2, Floor);
575    /// assert_eq!(log.to_string(), "1.660964047443681173935159714743");
576    /// assert_eq!(o, Less);
577    ///
578    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
579    ///     .0
580    ///     .log_base_power_of_2_round(2, Ceiling);
581    /// assert_eq!(log.to_string(), "1.660964047443681173935159714745");
582    /// assert_eq!(o, Greater);
583    ///
584    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
585    ///     .0
586    ///     .log_base_power_of_2_round(2, Nearest);
587    /// assert_eq!(log.to_string(), "1.660964047443681173935159714745");
588    /// assert_eq!(o, Greater);
589    /// ```
590    #[inline]
591    pub fn log_base_power_of_2_round(self, pow: i64, rm: RoundingMode) -> (Self, Ordering) {
592        let prec = self.significant_bits();
593        self.log_base_power_of_2_prec_round(pow, prec, rm)
594    }
595
596    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
597    /// integer $k$, rounding the result with the specified rounding mode. The base's exponent $k$
598    /// is `pow`, which may be negative. The [`Float`] is taken by reference. An [`Ordering`] is
599    /// also returned, indicating whether the rounded value is less than, equal to, or greater than
600    /// the exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
601    /// returns a `NaN` it also returns `Equal`.
602    ///
603    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
604    ///
605    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
606    /// description of the possible rounding modes.
607    ///
608    /// $$
609    /// f(x,k,m) = \log_{2^k} x+\varepsilon.
610    /// $$
611    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
612    ///   be 0.
613    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
614    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$, where $p$ is the precision of the input.
615    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
616    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
617    ///
618    /// If the output has a precision, it is the precision of the input.
619    ///
620    /// Special cases:
621    /// - $f(\text{NaN},k,m)=\text{NaN}$
622    /// - $f(\infty,k,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
623    /// - $f(-\infty,k,m)=\text{NaN}$
624    /// - $f(\pm0.0,k,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
625    /// - $f(1.0,k,m)=0.0$, and the result is exact
626    /// - $f(2^m,k,m')=m/k$, rounded to the precision of the input; the result is exact if and only
627    ///   if $m/k$ is representable with that precision (for example $\log_4 8=3/2$ is exact, but
628    ///   $\log_8 4=2/3$ is not)
629    /// - $f(x,k,m)=\text{NaN}$ for $x<0$
630    ///
631    /// Neither overflow nor underflow is possible.
632    ///
633    /// If you want to specify an output precision, consider using
634    /// [`Float::log_base_power_of_2_prec_round_ref`] instead. If you know you'll be using the
635    /// `Nearest` rounding mode, consider using `(&Float).log_base_power_of_2()` instead.
636    ///
637    /// # Worst-case complexity
638    /// $T(n) = O(n (\log n)^2 \log\log n)$
639    ///
640    /// $M(n) = O(n (\log n)^2)$
641    ///
642    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
643    ///
644    /// # Panics
645    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
646    /// result cannot be represented exactly with the input precision. (The result is exactly
647    /// representable if and only if the input is `NaN`, infinite, zero, equal to 1, or a power of 2
648    /// whose base-$2^k$ logarithm is representable with the input precision.)
649    ///
650    /// # Examples
651    /// ```
652    /// use malachite_base::rounding_modes::RoundingMode::*;
653    /// use malachite_float::Float;
654    /// use std::cmp::Ordering::*;
655    ///
656    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
657    ///     .0
658    ///     .log_base_power_of_2_round_ref(2, Floor);
659    /// assert_eq!(log.to_string(), "1.660964047443681173935159714743");
660    /// assert_eq!(o, Less);
661    ///
662    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
663    ///     .0
664    ///     .log_base_power_of_2_round_ref(2, Ceiling);
665    /// assert_eq!(log.to_string(), "1.660964047443681173935159714745");
666    /// assert_eq!(o, Greater);
667    ///
668    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
669    ///     .0
670    ///     .log_base_power_of_2_round_ref(2, Nearest);
671    /// assert_eq!(log.to_string(), "1.660964047443681173935159714745");
672    /// assert_eq!(o, Greater);
673    /// ```
674    #[inline]
675    pub fn log_base_power_of_2_round_ref(&self, pow: i64, rm: RoundingMode) -> (Self, Ordering) {
676        let prec = self.significant_bits();
677        self.log_base_power_of_2_prec_round_ref(pow, prec, rm)
678    }
679
680    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
681    /// integer $k$, in place, rounding the result to the specified precision and with the specified
682    /// rounding mode. The base's exponent $k$ is `pow`, which may be negative. An [`Ordering`] is
683    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
684    /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
685    /// sets the [`Float`] to `NaN` it also returns `Equal`.
686    ///
687    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
688    ///
689    /// See [`RoundingMode`] for a description of the possible rounding modes.
690    ///
691    /// $$
692    /// x \gets \log_{2^k} x+\varepsilon.
693    /// $$
694    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
695    ///   be 0.
696    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
697    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$.
698    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
699    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$.
700    ///
701    /// If the output has a precision, it is `prec`.
702    ///
703    /// See the [`Float::log_base_power_of_2_prec_round`] documentation for information on special
704    /// cases, overflow, and underflow.
705    ///
706    /// If you know you'll be using `Nearest`, consider using
707    /// [`Float::log_base_power_of_2_prec_assign`] instead. If you know that your target precision
708    /// is the precision of the input, consider using [`Float::log_base_power_of_2_round_assign`]
709    /// instead. If both of these things are true, consider using
710    /// [`Float::log_base_power_of_2_assign`] instead.
711    ///
712    /// # Worst-case complexity
713    /// $T(n) = O(n (\log n)^2 \log\log n)$
714    ///
715    /// $M(n) = O(n (\log n)^2)$
716    ///
717    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
718    ///
719    /// # Panics
720    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
721    /// is `Exact` but the result cannot be represented exactly with the given precision. (The
722    /// result is exactly representable if and only if the input is `NaN`, infinite, zero, equal to
723    /// 1, or a power of 2 whose base-$2^k$ logarithm is representable with the given precision.)
724    ///
725    /// # Examples
726    /// ```
727    /// use malachite_base::rounding_modes::RoundingMode::*;
728    /// use malachite_float::Float;
729    /// use std::cmp::Ordering::*;
730    ///
731    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
732    /// assert_eq!(x.log_base_power_of_2_prec_round_assign(2, 5, Floor), Less);
733    /// assert_eq!(x.to_string(), "1.62");
734    ///
735    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
736    /// assert_eq!(
737    ///     x.log_base_power_of_2_prec_round_assign(2, 5, Ceiling),
738    ///     Greater
739    /// );
740    /// assert_eq!(x.to_string(), "1.7");
741    ///
742    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
743    /// assert_eq!(
744    ///     x.log_base_power_of_2_prec_round_assign(2, 5, Nearest),
745    ///     Greater
746    /// );
747    /// assert_eq!(x.to_string(), "1.7");
748    ///
749    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
750    /// assert_eq!(x.log_base_power_of_2_prec_round_assign(3, 20, Floor), Less);
751    /// assert_eq!(x.to_string(), "1.107309");
752    ///
753    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
754    /// assert_eq!(
755    ///     x.log_base_power_of_2_prec_round_assign(3, 20, Ceiling),
756    ///     Greater
757    /// );
758    /// assert_eq!(x.to_string(), "1.107311");
759    ///
760    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
761    /// assert_eq!(
762    ///     x.log_base_power_of_2_prec_round_assign(3, 20, Nearest),
763    ///     Less
764    /// );
765    /// assert_eq!(x.to_string(), "1.107309");
766    /// ```
767    #[inline]
768    pub fn log_base_power_of_2_prec_round_assign(
769        &mut self,
770        pow: i64,
771        prec: u64,
772        rm: RoundingMode,
773    ) -> Ordering {
774        let (result, o) = core::mem::take(self).log_base_power_of_2_prec_round(pow, prec, rm);
775        *self = result;
776        o
777    }
778
779    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
780    /// integer $k$, in place, rounding the result to the nearest value of the specified precision.
781    /// The base's exponent $k$ is `pow`, which may be negative. An [`Ordering`] is returned,
782    /// indicating whether the rounded value is less than, equal to, or greater than the exact
783    /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
784    /// [`Float`] to `NaN` it also returns `Equal`.
785    ///
786    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
787    ///
788    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
789    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
790    /// description of the `Nearest` rounding mode.
791    ///
792    /// $$
793    /// x \gets \log_{2^k} x+\varepsilon.
794    /// $$
795    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
796    ///   be 0.
797    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
798    ///   |\log_{2^k} x|\rfloor-p}$.
799    ///
800    /// If the output has a precision, it is `prec`.
801    ///
802    /// See the [`Float::log_base_power_of_2_prec`] documentation for information on special cases,
803    /// overflow, and underflow.
804    ///
805    /// If you want to use a rounding mode other than `Nearest`, consider using
806    /// [`Float::log_base_power_of_2_prec_round_assign`] instead. If you know that your target
807    /// precision is the precision of the input, consider using
808    /// [`Float::log_base_power_of_2_assign`] instead.
809    ///
810    /// # Worst-case complexity
811    /// $T(n) = O(n (\log n)^2 \log\log n)$
812    ///
813    /// $M(n) = O(n (\log n)^2)$
814    ///
815    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
816    ///
817    /// # Panics
818    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
819    ///
820    /// # Examples
821    /// ```
822    /// use malachite_float::Float;
823    /// use std::cmp::Ordering::*;
824    ///
825    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
826    /// assert_eq!(x.log_base_power_of_2_prec_assign(2, 5), Greater);
827    /// assert_eq!(x.to_string(), "1.7");
828    ///
829    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
830    /// assert_eq!(x.log_base_power_of_2_prec_assign(3, 20), Less);
831    /// assert_eq!(x.to_string(), "1.107309");
832    /// ```
833    #[inline]
834    pub fn log_base_power_of_2_prec_assign(&mut self, pow: i64, prec: u64) -> Ordering {
835        self.log_base_power_of_2_prec_round_assign(pow, prec, Nearest)
836    }
837
838    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
839    /// integer $k$, in place, rounding the result with the specified rounding mode. The base's
840    /// exponent $k$ is `pow`, which may be negative. An [`Ordering`] is returned, indicating
841    /// whether the rounded value is less than, equal to, or greater than the exact value. Although
842    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
843    /// `NaN` it also returns `Equal`.
844    ///
845    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
846    ///
847    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
848    /// description of the possible rounding modes.
849    ///
850    /// $$
851    /// x \gets \log_{2^k} x+\varepsilon.
852    /// $$
853    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
854    ///   be 0.
855    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
856    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$, where $p$ is the precision of the input.
857    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
858    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
859    ///
860    /// If the output has a precision, it is the precision of the input.
861    ///
862    /// See the [`Float::log_base_power_of_2_round`] documentation for information on special cases,
863    /// overflow, and underflow.
864    ///
865    /// If you want to specify an output precision, consider using
866    /// [`Float::log_base_power_of_2_prec_round_assign`] instead. If you know you'll be using the
867    /// `Nearest` rounding mode, consider using [`Float::log_base_power_of_2_assign`] instead.
868    ///
869    /// # Worst-case complexity
870    /// $T(n) = O(n (\log n)^2 \log\log n)$
871    ///
872    /// $M(n) = O(n (\log n)^2)$
873    ///
874    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
875    ///
876    /// # Panics
877    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
878    /// result cannot be represented exactly with the input precision. (The result is exactly
879    /// representable if and only if the input is `NaN`, infinite, zero, equal to 1, or a power of 2
880    /// whose base-$2^k$ logarithm is representable with the input precision.)
881    ///
882    /// # Examples
883    /// ```
884    /// use malachite_base::rounding_modes::RoundingMode::*;
885    /// use malachite_float::Float;
886    /// use std::cmp::Ordering::*;
887    ///
888    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
889    /// assert_eq!(x.log_base_power_of_2_round_assign(2, Floor), Less);
890    /// assert_eq!(x.to_string(), "1.660964047443681173935159714743");
891    ///
892    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
893    /// assert_eq!(x.log_base_power_of_2_round_assign(2, Ceiling), Greater);
894    /// assert_eq!(x.to_string(), "1.660964047443681173935159714745");
895    ///
896    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
897    /// assert_eq!(x.log_base_power_of_2_round_assign(2, Nearest), Greater);
898    /// assert_eq!(x.to_string(), "1.660964047443681173935159714745");
899    /// ```
900    #[inline]
901    pub fn log_base_power_of_2_round_assign(&mut self, pow: i64, rm: RoundingMode) -> Ordering {
902        let prec = self.significant_bits();
903        self.log_base_power_of_2_prec_round_assign(pow, prec, rm)
904    }
905
906    /// Computes $\log_{2^k} x$, where $x$ is a [`Rational`] and the base is $2^k$ for some nonzero
907    /// integer $k$, rounding the result to the specified precision and with the specified rounding
908    /// mode and returning the result as a [`Float`]. The base's exponent $k$ is `pow`, which may be
909    /// negative. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
910    /// whether the rounded value is less than, equal to, or greater than the exact value. Although
911    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
912    /// returns `Equal`.
913    ///
914    /// The base-$2^k$ logarithm of any negative number is `NaN`.
915    ///
916    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
917    /// or too small to be representable as [`Float`]s.
918    ///
919    /// See [`RoundingMode`] for a description of the possible rounding modes.
920    ///
921    /// $$
922    /// f(x,k,p,m) = \log_{2^k} x+\varepsilon.
923    /// $$
924    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
925    ///   be 0.
926    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
927    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$.
928    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
929    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$.
930    ///
931    /// If the output has a precision, it is `prec`.
932    ///
933    /// Special cases:
934    /// - $f(0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
935    /// - $f(x,k,p,m)=\text{NaN}$ for $x<0$
936    /// - $f(1,k,p,m)=0.0$, and the result is exact
937    /// - $f(2^m,k,p,m')=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
938    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
939    ///   is not). This includes negative powers of 2 like $1/4$, and powers of 2 whose exponents
940    ///   $m$ lie far outside the exponent range of [`Float`].
941    ///
942    /// If you know you'll be using `Nearest`, consider using
943    /// [`Float::log_base_power_of_2_rational_prec`] instead.
944    ///
945    /// # Worst-case complexity
946    /// $T(n) = O(n (\log n)^2 \log\log n)$
947    ///
948    /// $M(n) = O(n (\log n)^2)$
949    ///
950    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
951    ///
952    /// # Panics
953    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
954    /// is `Exact` but the result cannot be represented exactly with the given precision. (The
955    /// result is exactly representable if and only if $x\leq 0$ or $x$ is a power of 2 whose
956    /// base-$2^k$ logarithm is representable with the given precision.)
957    ///
958    /// # Examples
959    /// ```
960    /// use malachite_base::rounding_modes::RoundingMode::*;
961    /// use malachite_float::Float;
962    /// use malachite_q::Rational;
963    /// use std::cmp::Ordering::*;
964    ///
965    /// let (log, o) = Float::log_base_power_of_2_rational_prec_round(
966    ///     Rational::from_unsigneds(3u8, 5),
967    ///     2,
968    ///     20,
969    ///     Floor,
970    /// );
971    /// assert_eq!(log.to_string(), "-0.3684831");
972    /// assert_eq!(o, Less);
973    ///
974    /// let (log, o) = Float::log_base_power_of_2_rational_prec_round(
975    ///     Rational::from_unsigneds(3u8, 5),
976    ///     2,
977    ///     20,
978    ///     Ceiling,
979    /// );
980    /// assert_eq!(log.to_string(), "-0.3684826");
981    /// assert_eq!(o, Greater);
982    /// ```
983    #[allow(clippy::needless_pass_by_value)]
984    #[inline]
985    pub fn log_base_power_of_2_rational_prec_round(
986        x: Rational,
987        pow: i64,
988        prec: u64,
989        rm: RoundingMode,
990    ) -> (Self, Ordering) {
991        Self::log_base_power_of_2_rational_prec_round_ref(&x, pow, prec, rm)
992    }
993
994    /// Computes $\log_{2^k} x$, where $x$ is a [`Rational`] and the base is $2^k$ for some nonzero
995    /// integer $k$, rounding the result to the specified precision and with the specified rounding
996    /// mode and returning the result as a [`Float`]. The base's exponent $k$ is `pow`, which may be
997    /// negative. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
998    /// indicating whether the rounded value is less than, equal to, or greater than the exact
999    /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
1000    /// `NaN` it also returns `Equal`.
1001    ///
1002    /// The base-$2^k$ logarithm of any negative number is `NaN`.
1003    ///
1004    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1005    /// or too small to be representable as [`Float`]s.
1006    ///
1007    /// See [`RoundingMode`] for a description of the possible rounding modes.
1008    ///
1009    /// $$
1010    /// f(x,k,p,m) = \log_{2^k} x+\varepsilon.
1011    /// $$
1012    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1013    ///   be 0.
1014    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1015    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p+1}$.
1016    /// - If $\log_{2^k} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1017    ///   2^{\lfloor\log_2 |\log_{2^k} x|\rfloor-p}$.
1018    ///
1019    /// If the output has a precision, it is `prec`.
1020    ///
1021    /// Special cases:
1022    /// - $f(0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1023    /// - $f(x,k,p,m)=\text{NaN}$ for $x<0$
1024    /// - $f(1,k,p,m)=0.0$, and the result is exact
1025    /// - $f(2^m,k,p,m')=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
1026    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
1027    ///   is not). This includes negative powers of 2 like $1/4$, and powers of 2 whose exponents
1028    ///   $m$ lie far outside the exponent range of [`Float`].
1029    ///
1030    /// If you know you'll be using `Nearest`, consider using
1031    /// [`Float::log_base_power_of_2_rational_prec_ref`] instead.
1032    ///
1033    /// # Worst-case complexity
1034    /// $T(n) = O(n (\log n)^2 \log\log n)$
1035    ///
1036    /// $M(n) = O(n (\log n)^2)$
1037    ///
1038    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1039    ///
1040    /// # Panics
1041    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
1042    /// is `Exact` but the result cannot be represented exactly with the given precision. (The
1043    /// result is exactly representable if and only if $x\leq 0$ or $x$ is a power of 2 whose
1044    /// base-$2^k$ logarithm is representable with the given precision.)
1045    ///
1046    /// # Examples
1047    /// ```
1048    /// use malachite_base::rounding_modes::RoundingMode::*;
1049    /// use malachite_float::Float;
1050    /// use malachite_q::Rational;
1051    /// use std::cmp::Ordering::*;
1052    ///
1053    /// let (log, o) = Float::log_base_power_of_2_rational_prec_round_ref(
1054    ///     &Rational::from_unsigneds(3u8, 5),
1055    ///     2,
1056    ///     20,
1057    ///     Floor,
1058    /// );
1059    /// assert_eq!(log.to_string(), "-0.3684831");
1060    /// assert_eq!(o, Less);
1061    ///
1062    /// let (log, o) = Float::log_base_power_of_2_rational_prec_round_ref(
1063    ///     &Rational::from_unsigneds(3u8, 5),
1064    ///     2,
1065    ///     20,
1066    ///     Ceiling,
1067    /// );
1068    /// assert_eq!(log.to_string(), "-0.3684826");
1069    /// assert_eq!(o, Greater);
1070    ///
1071    /// // log_4(8) = 3/2, exactly representable
1072    /// let (log, o) = Float::log_base_power_of_2_rational_prec_round_ref(
1073    ///     &Rational::from(8u32),
1074    ///     2,
1075    ///     10,
1076    ///     Nearest,
1077    /// );
1078    /// assert_eq!(log.to_string(), "1.5");
1079    /// assert_eq!(o, Equal);
1080    /// ```
1081    pub fn log_base_power_of_2_rational_prec_round_ref(
1082        x: &Rational,
1083        pow: i64,
1084        prec: u64,
1085        rm: RoundingMode,
1086    ) -> (Self, Ordering) {
1087        assert_ne!(prec, 0);
1088        assert_ne!(pow, 0, "Cannot take base-1 logarithm");
1089        match x.sign() {
1090            Equal => {
1091                return (
1092                    if pow > 0 {
1093                        float_negative_infinity!()
1094                    } else {
1095                        float_infinity!()
1096                    },
1097                    Equal,
1098                );
1099            }
1100            Less => return (float_nan!(), Equal),
1101            Greater => {}
1102        }
1103        // If x is 2^m, then log_2(x) = m and the result is the rational m / pow (exact when
1104        // representable at the target precision).
1105        if let Some(m) = x.checked_log_base_2() {
1106            return Self::from(m).div_prec_round(Self::from(pow), prec, rm);
1107        }
1108        // The result is never exactly representable otherwise.
1109        assert_ne!(rm, Exact, "Inexact log_base_power_of_2");
1110        log_base_power_of_2_rational_prec_round_helper(x, pow, prec, rm)
1111    }
1112
1113    /// Computes $\log_{2^k} x$, where $x$ is a [`Rational`] and the base is $2^k$ for some nonzero
1114    /// integer $k$, rounding the result to the nearest value of the specified precision and
1115    /// returning the result as a [`Float`]. The base's exponent $k$ is `pow`, which may be
1116    /// negative. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
1117    /// whether the rounded value is less than, equal to, or greater than the exact value. Although
1118    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1119    /// returns `Equal`.
1120    ///
1121    /// The base-$2^k$ logarithm of any negative number is `NaN`.
1122    ///
1123    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1124    /// or too small to be representable as [`Float`]s.
1125    ///
1126    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
1127    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1128    /// description of the `Nearest` rounding mode.
1129    ///
1130    /// $$
1131    /// f(x,k,p) = \log_{2^k} x+\varepsilon.
1132    /// $$
1133    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1134    ///   be 0.
1135    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1136    ///   |\log_{2^k} x|\rfloor-p}$.
1137    ///
1138    /// If the output has a precision, it is `prec`.
1139    ///
1140    /// Special cases:
1141    /// - $f(0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1142    /// - $f(x,k,p)=\text{NaN}$ for $x<0$
1143    /// - $f(1,k,p)=0.0$, and the result is exact
1144    /// - $f(2^m,k,p)=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
1145    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
1146    ///   is not). This includes negative powers of 2 like $1/4$, and powers of 2 whose exponents
1147    ///   $m$ lie far outside the exponent range of [`Float`].
1148    ///
1149    /// If you want to use a rounding mode other than `Nearest`, consider using
1150    /// [`Float::log_base_power_of_2_rational_prec_round`] instead.
1151    ///
1152    /// # Worst-case complexity
1153    /// $T(n) = O(n (\log n)^2 \log\log n)$
1154    ///
1155    /// $M(n) = O(n (\log n)^2)$
1156    ///
1157    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1158    ///
1159    /// # Panics
1160    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
1161    ///
1162    /// # Examples
1163    /// ```
1164    /// use malachite_float::Float;
1165    /// use malachite_q::Rational;
1166    /// use std::cmp::Ordering::*;
1167    ///
1168    /// let (log, o) =
1169    ///     Float::log_base_power_of_2_rational_prec(Rational::from_unsigneds(3u8, 5), 2, 20);
1170    /// assert_eq!(log.to_string(), "-0.3684826");
1171    /// assert_eq!(o, Greater);
1172    /// ```
1173    #[inline]
1174    pub fn log_base_power_of_2_rational_prec(x: Rational, pow: i64, prec: u64) -> (Self, Ordering) {
1175        Self::log_base_power_of_2_rational_prec_round(x, pow, prec, Nearest)
1176    }
1177
1178    /// Computes $\log_{2^k} x$, where $x$ is a [`Rational`] and the base is $2^k$ for some nonzero
1179    /// integer $k$, rounding the result to the nearest value of the specified precision and
1180    /// returning the result as a [`Float`]. The base's exponent $k$ is `pow`, which may be
1181    /// negative. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
1182    /// indicating whether the rounded value is less than, equal to, or greater than the exact
1183    /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
1184    /// `NaN` it also returns `Equal`.
1185    ///
1186    /// The base-$2^k$ logarithm of any negative number is `NaN`.
1187    ///
1188    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1189    /// or too small to be representable as [`Float`]s.
1190    ///
1191    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
1192    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1193    /// description of the `Nearest` rounding mode.
1194    ///
1195    /// $$
1196    /// f(x,k,p) = \log_{2^k} x+\varepsilon.
1197    /// $$
1198    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1199    ///   be 0.
1200    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1201    ///   |\log_{2^k} x|\rfloor-p}$.
1202    ///
1203    /// If the output has a precision, it is `prec`.
1204    ///
1205    /// Special cases:
1206    /// - $f(0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1207    /// - $f(x,k,p)=\text{NaN}$ for $x<0$
1208    /// - $f(1,k,p)=0.0$, and the result is exact
1209    /// - $f(2^m,k,p)=m/k$, rounded to precision $p$; the result is exact if and only if $m/k$ is
1210    ///   representable with precision $p$ (for example $\log_4 8=3/2$ is exact, but $\log_8 4=2/3$
1211    ///   is not). This includes negative powers of 2 like $1/4$, and powers of 2 whose exponents
1212    ///   $m$ lie far outside the exponent range of [`Float`].
1213    ///
1214    /// If you want to use a rounding mode other than `Nearest`, consider using
1215    /// [`Float::log_base_power_of_2_rational_prec_round_ref`] instead.
1216    ///
1217    /// # Worst-case complexity
1218    /// $T(n) = O(n (\log n)^2 \log\log n)$
1219    ///
1220    /// $M(n) = O(n (\log n)^2)$
1221    ///
1222    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1223    ///
1224    /// # Panics
1225    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
1226    ///
1227    /// # Examples
1228    /// ```
1229    /// use malachite_float::Float;
1230    /// use malachite_q::Rational;
1231    /// use std::cmp::Ordering::*;
1232    ///
1233    /// let (log, o) =
1234    ///     Float::log_base_power_of_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 2, 20);
1235    /// assert_eq!(log.to_string(), "-0.3684826");
1236    /// assert_eq!(o, Greater);
1237    /// ```
1238    #[inline]
1239    pub fn log_base_power_of_2_rational_prec_ref(
1240        x: &Rational,
1241        pow: i64,
1242        prec: u64,
1243    ) -> (Self, Ordering) {
1244        Self::log_base_power_of_2_rational_prec_round_ref(x, pow, prec, Nearest)
1245    }
1246}
1247
1248impl LogBasePowerOf2<i64> for Float {
1249    type Output = Self;
1250
1251    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
1252    /// integer $k$, taking it by value. The base's exponent $k$ is `pow`, which may be negative.
1253    ///
1254    /// If the output has a precision, it is the precision of the input. If the logarithm is
1255    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1256    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1257    /// rounding mode.
1258    ///
1259    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
1260    ///
1261    /// $$
1262    /// f(x,k) = \log_{2^k} x+\varepsilon.
1263    /// $$
1264    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1265    ///   be 0.
1266    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1267    ///   |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
1268    ///
1269    /// Special cases:
1270    /// - $f(\text{NaN},k)=\text{NaN}$
1271    /// - $f(\infty,k)=\infty$ if $k>0$, and $-\infty$ if $k<0$
1272    /// - $f(-\infty,k)=\text{NaN}$
1273    /// - $f(\pm0.0,k)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1274    /// - $f(1.0,k)=0.0$, and the result is exact
1275    /// - $f(2^m,k)=m/k$, rounded to the precision of the input; the result is exact if and only if
1276    ///   $m/k$ is representable with that precision (for example $\log_4 8=3/2$ is exact, but
1277    ///   $\log_8 4=2/3$ is not)
1278    /// - $f(x,k)=\text{NaN}$ for $x<0$
1279    ///
1280    /// Neither overflow nor underflow is possible.
1281    ///
1282    /// If you want to use a rounding mode other than `Nearest`, consider using
1283    /// [`Float::log_base_power_of_2_round`] instead. If you want to specify the output precision,
1284    /// consider using [`Float::log_base_power_of_2_prec`]. If you want both of these things,
1285    /// consider using [`Float::log_base_power_of_2_prec_round`].
1286    ///
1287    /// # Worst-case complexity
1288    /// $T(n) = O(n (\log n)^2 \log\log n)$
1289    ///
1290    /// $M(n) = O(n (\log n)^2)$
1291    ///
1292    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1293    ///
1294    /// # Panics
1295    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1296    ///
1297    /// # Examples
1298    /// ```
1299    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2;
1300    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1301    /// use malachite_float::Float;
1302    ///
1303    /// assert!(Float::NAN.log_base_power_of_2(2).is_nan());
1304    /// assert_eq!(Float::INFINITY.log_base_power_of_2(2), Float::INFINITY);
1305    /// assert_eq!(
1306    ///     Float::INFINITY.log_base_power_of_2(-2),
1307    ///     Float::NEGATIVE_INFINITY
1308    /// );
1309    /// assert!(Float::NEGATIVE_INFINITY.log_base_power_of_2(2).is_nan());
1310    /// assert_eq!(
1311    ///     Float::from_unsigned_prec(10u32, 100)
1312    ///         .0
1313    ///         .log_base_power_of_2(2)
1314    ///         .to_string(),
1315    ///     "1.660964047443681173935159714745"
1316    /// );
1317    /// assert!(Float::from_signed_prec(-10, 100)
1318    ///     .0
1319    ///     .log_base_power_of_2(2)
1320    ///     .is_nan());
1321    /// ```
1322    #[inline]
1323    fn log_base_power_of_2(self, pow: i64) -> Self {
1324        let prec = self.significant_bits();
1325        self.log_base_power_of_2_prec_round(pow, prec, Nearest).0
1326    }
1327}
1328
1329impl LogBasePowerOf2<i64> for &Float {
1330    type Output = Float;
1331
1332    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
1333    /// integer $k$, taking it by reference. The base's exponent $k$ is `pow`, which may be
1334    /// negative.
1335    ///
1336    /// If the output has a precision, it is the precision of the input. If the logarithm is
1337    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1338    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1339    /// rounding mode.
1340    ///
1341    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
1342    ///
1343    /// $$
1344    /// f(x,k) = \log_{2^k} x+\varepsilon.
1345    /// $$
1346    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1347    ///   be 0.
1348    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1349    ///   |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
1350    ///
1351    /// Special cases:
1352    /// - $f(\text{NaN},k)=\text{NaN}$
1353    /// - $f(\infty,k)=\infty$ if $k>0$, and $-\infty$ if $k<0$
1354    /// - $f(-\infty,k)=\text{NaN}$
1355    /// - $f(\pm0.0,k)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1356    /// - $f(1.0,k)=0.0$, and the result is exact
1357    /// - $f(2^m,k)=m/k$, rounded to the precision of the input; the result is exact if and only if
1358    ///   $m/k$ is representable with that precision (for example $\log_4 8=3/2$ is exact, but
1359    ///   $\log_8 4=2/3$ is not)
1360    /// - $f(x,k)=\text{NaN}$ for $x<0$
1361    ///
1362    /// Neither overflow nor underflow is possible.
1363    ///
1364    /// If you want to use a rounding mode other than `Nearest`, consider using
1365    /// [`Float::log_base_power_of_2_round_ref`] instead. If you want to specify the output
1366    /// precision, consider using [`Float::log_base_power_of_2_prec_ref`]. If you want both of these
1367    /// things, consider using [`Float::log_base_power_of_2_prec_round_ref`].
1368    ///
1369    /// # Worst-case complexity
1370    /// $T(n) = O(n (\log n)^2 \log\log n)$
1371    ///
1372    /// $M(n) = O(n (\log n)^2)$
1373    ///
1374    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1375    ///
1376    /// # Panics
1377    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1378    ///
1379    /// # Examples
1380    /// ```
1381    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2;
1382    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1383    /// use malachite_float::Float;
1384    ///
1385    /// assert!((&Float::NAN).log_base_power_of_2(2).is_nan());
1386    /// assert_eq!((&Float::INFINITY).log_base_power_of_2(2), Float::INFINITY);
1387    /// assert_eq!(
1388    ///     (&Float::INFINITY).log_base_power_of_2(-2),
1389    ///     Float::NEGATIVE_INFINITY
1390    /// );
1391    /// assert!((&Float::NEGATIVE_INFINITY).log_base_power_of_2(2).is_nan());
1392    /// assert_eq!(
1393    ///     (&Float::from_unsigned_prec(10u32, 100).0)
1394    ///         .log_base_power_of_2(2)
1395    ///         .to_string(),
1396    ///     "1.660964047443681173935159714745"
1397    /// );
1398    /// assert!((&Float::from_signed_prec(-10, 100).0)
1399    ///     .log_base_power_of_2(2)
1400    ///     .is_nan());
1401    /// ```
1402    #[inline]
1403    fn log_base_power_of_2(self, pow: i64) -> Float {
1404        let prec = self.significant_bits();
1405        self.log_base_power_of_2_prec_round_ref(pow, prec, Nearest)
1406            .0
1407    }
1408}
1409
1410impl LogBasePowerOf2Assign<i64> for Float {
1411    /// Computes $\log_{2^k} x$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
1412    /// integer $k$, in place. The base's exponent $k$ is `pow`, which may be negative.
1413    ///
1414    /// If the output has a precision, it is the precision of the input. If the logarithm is
1415    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1416    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1417    /// rounding mode.
1418    ///
1419    /// The base-$2^k$ logarithm of any nonzero negative number is `NaN`.
1420    ///
1421    /// $$
1422    /// x \gets \log_{2^k} x+\varepsilon.
1423    /// $$
1424    /// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1425    ///   be 0.
1426    /// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1427    ///   |\log_{2^k} x|\rfloor-p}$, where $p$ is the precision of the input.
1428    ///
1429    /// See the [`Float::log_base_power_of_2`] documentation for information on special cases,
1430    /// overflow, and underflow.
1431    ///
1432    /// If you want to use a rounding mode other than `Nearest`, consider using
1433    /// [`Float::log_base_power_of_2_round_assign`] instead. If you want to specify the output
1434    /// precision, consider using [`Float::log_base_power_of_2_prec_assign`]. If you want both of
1435    /// these things, consider using [`Float::log_base_power_of_2_prec_round_assign`].
1436    ///
1437    /// # Worst-case complexity
1438    /// $T(n) = O(n (\log n)^2 \log\log n)$
1439    ///
1440    /// $M(n) = O(n (\log n)^2)$
1441    ///
1442    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1443    ///
1444    /// # Panics
1445    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1446    ///
1447    /// # Examples
1448    /// ```
1449    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2Assign;
1450    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1451    /// use malachite_float::Float;
1452    ///
1453    /// let mut x = Float::NAN;
1454    /// x.log_base_power_of_2_assign(2);
1455    /// assert!(x.is_nan());
1456    ///
1457    /// let mut x = Float::INFINITY;
1458    /// x.log_base_power_of_2_assign(2);
1459    /// assert_eq!(x, Float::INFINITY);
1460    ///
1461    /// let mut x = Float::INFINITY;
1462    /// x.log_base_power_of_2_assign(-2);
1463    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
1464    ///
1465    /// let mut x = Float::NEGATIVE_INFINITY;
1466    /// x.log_base_power_of_2_assign(2);
1467    /// assert!(x.is_nan());
1468    ///
1469    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
1470    /// x.log_base_power_of_2_assign(2);
1471    /// assert_eq!(x.to_string(), "1.660964047443681173935159714745");
1472    ///
1473    /// let mut x = Float::from_signed_prec(-10, 100).0;
1474    /// x.log_base_power_of_2_assign(2);
1475    /// assert!(x.is_nan());
1476    /// ```
1477    #[inline]
1478    fn log_base_power_of_2_assign(&mut self, pow: i64) {
1479        let prec = self.significant_bits();
1480        self.log_base_power_of_2_prec_round_assign(pow, prec, Nearest);
1481    }
1482}
1483
1484/// Computes $\log_{2^k} x$, the base-$2^k$ logarithm of a primitive float, where the base is $2^k$
1485/// for some nonzero integer $k$. The exponent $k$ is `pow`, which may be negative. Using this
1486/// function is more accurate than computing the logarithm using the standard library, whose `log2`
1487/// is not always correctly rounded.
1488///
1489/// The base-$2^k$ logarithm of any negative number is `NaN`.
1490///
1491/// $$
1492/// f(x,k) = \log_{2^k} x+\varepsilon.
1493/// $$
1494/// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1495///   0.
1496/// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{2^k}
1497///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
1498///   if `T` is a [`f64`], but less if the output is subnormal).
1499///
1500/// Special cases:
1501/// - $f(\text{NaN},k)=\text{NaN}$
1502/// - $f(\infty,k)=\infty$ if $k>0$, and $-\infty$ if $k<0$
1503/// - $f(-\infty,k)=\text{NaN}$
1504/// - $f(\pm0.0,k)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1505/// - $f(1.0,k)=0.0$
1506/// - $f(x,k)=\text{NaN}$ for $x<0$
1507///
1508/// Neither overflow nor underflow is possible.
1509///
1510/// # Worst-case complexity
1511/// Constant time and additional memory.
1512///
1513/// # Panics
1514/// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1515///
1516/// # Examples
1517/// ```
1518/// use malachite_base::num::float::NiceFloat;
1519/// use malachite_float::arithmetic::log_base_power_of_2::primitive_float_log_base_power_of_2;
1520///
1521/// assert!(primitive_float_log_base_power_of_2(f32::NAN, 2).is_nan());
1522/// // log_4(16) = 2
1523/// assert_eq!(
1524///     NiceFloat(primitive_float_log_base_power_of_2(16.0f32, 2)),
1525///     NiceFloat(2.0)
1526/// );
1527/// // log_4(8) = 3/2
1528/// assert_eq!(
1529///     NiceFloat(primitive_float_log_base_power_of_2(8.0f32, 2)),
1530///     NiceFloat(1.5)
1531/// );
1532/// // log_8(64) = 2
1533/// assert_eq!(
1534///     NiceFloat(primitive_float_log_base_power_of_2(64.0f32, 3)),
1535///     NiceFloat(2.0)
1536/// );
1537/// // log_4(10)
1538/// assert_eq!(
1539///     NiceFloat(primitive_float_log_base_power_of_2(10.0f32, 2)),
1540///     NiceFloat(1.660964)
1541/// );
1542/// // log_(1/2)(8) = -3
1543/// assert_eq!(
1544///     NiceFloat(primitive_float_log_base_power_of_2(8.0f32, -1)),
1545///     NiceFloat(-3.0)
1546/// );
1547/// ```
1548#[inline]
1549#[allow(clippy::type_repetition_in_bounds)]
1550pub fn primitive_float_log_base_power_of_2<T: PrimitiveFloat>(x: T, pow: i64) -> T
1551where
1552    Float: From<T> + PartialOrd<T>,
1553    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1554{
1555    emulate_float_to_float_fn(|x, prec| Float::log_base_power_of_2_prec(x, pow, prec), x)
1556}
1557
1558/// Computes $\log_{2^k} x$, the base-$2^k$ logarithm of a [`Rational`], where the base is $2^k$ for
1559/// some nonzero integer $k$, returning a primitive float result. The exponent $k$ is `pow`, which
1560/// may be negative.
1561///
1562/// If the logarithm is equidistant from two primitive floats, the primitive float with fewer 1s in
1563/// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
1564/// mode.
1565///
1566/// The base-$2^k$ logarithm of any negative number is `NaN`.
1567///
1568/// $$
1569/// f(x,k) = \log_{2^k} x+\varepsilon.
1570/// $$
1571/// - If $\log_{2^k} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1572///   0.
1573/// - If $\log_{2^k} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{2^k}
1574///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
1575///   if `T` is a [`f64`], but less if the output is subnormal).
1576///
1577/// Special cases:
1578/// - $f(0,k)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1579/// - $f(x,k)=\text{NaN}$ for $x<0$
1580/// - $f(1,k)=0.0$
1581///
1582/// Neither overflow nor underflow is possible.
1583///
1584/// # Worst-case complexity
1585/// Constant time and additional memory.
1586///
1587/// # Panics
1588/// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1589///
1590/// # Examples
1591/// ```
1592/// use malachite_base::num::basic::traits::{NegativeInfinity, Zero};
1593/// use malachite_base::num::float::NiceFloat;
1594/// use malachite_float::arithmetic::log_base_power_of_2::*;
1595/// use malachite_q::Rational;
1596///
1597/// assert_eq!(
1598///     NiceFloat(primitive_float_log_base_power_of_2_rational::<f64>(
1599///         &Rational::ZERO,
1600///         2
1601///     )),
1602///     NiceFloat(f64::NEGATIVE_INFINITY)
1603/// );
1604/// assert_eq!(
1605///     NiceFloat(primitive_float_log_base_power_of_2_rational::<f64>(
1606///         &Rational::ZERO,
1607///         -2
1608///     )),
1609///     NiceFloat(f64::INFINITY)
1610/// );
1611/// // log_4(1/3)
1612/// assert_eq!(
1613///     NiceFloat(primitive_float_log_base_power_of_2_rational::<f64>(
1614///         &Rational::from_unsigneds(1u8, 3),
1615///         2
1616///     )),
1617///     NiceFloat(-0.792481250360578)
1618/// );
1619/// // log_4(10000)
1620/// assert_eq!(
1621///     NiceFloat(primitive_float_log_base_power_of_2_rational::<f64>(
1622///         &Rational::from(10000),
1623///         2
1624///     )),
1625///     NiceFloat(6.643856189774724)
1626/// );
1627/// assert_eq!(
1628///     NiceFloat(primitive_float_log_base_power_of_2_rational::<f64>(
1629///         &Rational::from(-10000),
1630///         2
1631///     )),
1632///     NiceFloat(f64::NAN)
1633/// );
1634/// ```
1635#[inline]
1636#[allow(clippy::type_repetition_in_bounds)]
1637pub fn primitive_float_log_base_power_of_2_rational<T: PrimitiveFloat>(x: &Rational, pow: i64) -> T
1638where
1639    Float: PartialOrd<T>,
1640    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1641{
1642    emulate_rational_to_float_fn(
1643        |x, prec| Float::log_base_power_of_2_rational_prec_ref(x, pow, prec),
1644        x,
1645    )
1646}