Skip to main content

malachite_float/arithmetic/
log_base_2.rs

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