Skip to main content

malachite_float/arithmetic/
log_base_power_of_2_1_plus_x.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::{Infinity, NaN, Zero};
10use crate::arithmetic::log_base_2_1_plus_x::log_base_2_1_plus_x_exact;
11use crate::{Float, emulate_float_to_float_fn, float_infinity, float_nan, float_negative_infinity};
12use core::cmp::Ordering::{self, *};
13use malachite_base::num::arithmetic::traits::{
14    CeilingLogBase2, IsPowerOf2, LogBasePowerOf2Of1PlusX, LogBasePowerOf2Of1PlusXAssign,
15};
16use malachite_base::num::basic::floats::PrimitiveFloat;
17use malachite_base::num::basic::integers::PrimitiveInt;
18use malachite_base::num::comparison::traits::PartialOrdAbs;
19use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
20use malachite_base::num::logic::traits::SignificantBits;
21use malachite_base::rounding_modes::RoundingMode::{self, *};
22use malachite_nz::natural::arithmetic::float_extras::float_can_round;
23use malachite_nz::platform::Limb;
24
25// The computation of log_base_power_of_2_1_plus_x(x, pow) is done by log_{2^pow}(1 + x) = log_2(1 +
26// x) / pow, where the input is finite, nonzero, and greater than -1.
27fn log_base_power_of_2_1_plus_x_prec_round_normal(
28    x: &Float,
29    pow: i64,
30    prec: u64,
31    rm: RoundingMode,
32) -> (Float, Ordering) {
33    // log_{2^pow}(1 + x) is undefined for x < -1.
34    match x.partial_cmp(&-1i32).unwrap() {
35        // 1 + x = 0, so log_2(1 + x) = -infinity.
36        Equal => {
37            return (
38                if pow > 0 {
39                    float_negative_infinity!()
40                } else {
41                    float_infinity!()
42                },
43                Equal,
44            );
45        }
46        Less => return (float_nan!(), Equal),
47        _ => {}
48    }
49    // If 1 + x is exactly 2^m, then log_2(1 + x) = m and the result is the rational m / pow (exact
50    // when representable at the target precision).
51    if let Some(m) = log_base_2_1_plus_x_exact(x) {
52        return Float::from(m).div_prec_round(Float::from(pow), prec, rm);
53    }
54    // The result is never exactly representable otherwise.
55    assert_ne!(rm, Exact, "Inexact log_base_power_of_2_1_plus_x");
56    let pow_f = Float::from(pow);
57    let e_pow = i64::from(pow_f.get_exponent().unwrap());
58    let min_exp = i64::from(Float::MIN_EXPONENT);
59    // If x = 2^k for a k large enough that 1 + x is astronomically close to 2^k, then log_2(1 + x)
60    // is k plus a positive infinitesimal (delta < 2^(2 - expx)), so log_{2^pow}(1 + x) is k / pow
61    // nudged infinitesimally away from k / pow (toward +infinity when pow > 0, toward -infinity
62    // when pow < 0). The Ziv loop below could never resolve this: log_2(1 + x) rounds to exactly k
63    // at every working precision (this is log_base_2_1_plus_x's own `_special` regime), so when k /
64    // pow is exactly representable the rounding test can never certify it and the precision grows
65    // without bound. Handle it directly, but only once delta is below a quarter ulp of the *result*
66    // k / pow (note the deviation must be measured at the result's scale, e_res, not k's scale --
67    // dividing by pow can make the ulp finer relative to delta); otherwise delta is large enough
68    // that the ordinary Ziv loop both terminates and is needed for correctness.
69    if x.is_power_of_2() {
70        let expx = i64::from(x.get_exponent().unwrap());
71        let k = expx - 1; // x = 2^k
72        if k >= 1 {
73            // log_2(1 + x) lies in (k, k + delta). Represent "just above k" at a precision high
74            // enough that the nudge, once divided by pow, stays far below one ulp of k / pow (so it
75            // shares k / pow's rounding cell) yet is strictly nonzero. This pushes a representable
76            // or tied k / pow off the boundary in the correct direction, so div_prec_round returns
77            // the correctly-rounded value and ternary for the true (infinitesimally offset) result.
78            let high_prec = prec + e_pow.unsigned_abs() + Limb::WIDTH;
79            let mut t = Float::from_signed_prec(k, high_prec).0;
80            t.increment();
81            let (res, o) = t.div_prec_round(pow_f.clone(), prec, rm);
82            let e_res = i64::from(res.get_exponent().unwrap());
83            if 2 - expx < e_res - i64::exact_from(prec) - 1 {
84                return (res, o);
85            }
86        }
87    }
88    let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
89    let mut increment = Limb::WIDTH;
90    loop {
91        // log_2(1 + x), correctly rounded to working_prec.
92        let num = x.log_base_2_1_plus_x_prec_ref(working_prec).0;
93        // log_2(1 + x) is always within the Float exponent range, but dividing by pow (with |pow| >
94        // 1) can push the result below MIN_EXPONENT; overflow is impossible, since |pow| >= 1 means
95        // |result| <= |log_2(1 + x)|. The quotient's exponent is e_num - e_pow or e_num - e_pow +
96        // 1. When the result underflows, the Ziv test below can never resolve it (the quotient
97        // clamps to a power of 2 at MIN_EXPONENT), so hand the rounding to div_prec_round, which
98        // clamps to zero or the minimum positive value per the rounding mode. The exact quotient
99        // exponent is resolved only in the narrow band where the cheap exponent bound is
100        // inconclusive (then e_num - e_pow == min_exp - 1, so the result underflows iff |log_2(1 +
101        // x) / pow| < 2^(min_exp - 1), i.e. iff |log_2(1 + x)| * 2^(1 - min_exp) < |pow|). The left
102        // shift only adjusts the exponent (the shifted value's exponent is e_pow, well within
103        // range), so this avoids converting a near-MIN_EXPONENT `num` to a `Rational` with a
104        // ~2^30-bit denominator.
105        let e_num = i64::from(num.get_exponent().unwrap());
106        if e_num - e_pow + 1 < min_exp
107            || (e_num - e_pow < min_exp && (&num << u64::exact_from(1 - min_exp)).lt_abs(&pow_f))
108        {
109            return num.div_prec_round(pow_f, prec, rm);
110        }
111        // log_2(1 + x) / pow, with two correctly-rounded operations: log_base_2_1_plus_x (at most
112        // 1/2 ulp) and division by the exact integer pow (at most 1/2 ulp). The relative error is
113        // thus below 2^(1 - working_prec), so working_prec - 2 correct bits suffice for rounding.
114        // (log_base_2_1_plus_x itself handles inputs x = 2^k with k so large that 1 + x is
115        // astronomically close to a power of 2, so no extra precision is needed here.)
116        let t = num.div_prec(pow_f.clone(), working_prec).0;
117        if float_can_round(t.significand_ref().unwrap(), working_prec - 2, prec, rm) {
118            return Float::from_float_prec_round(t, prec, rm);
119        }
120        // Increase the precision.
121        working_prec += increment;
122        increment = working_prec >> 1;
123    }
124}
125
126impl Float {
127    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
128    /// integer $k$, rounding the result to the specified precision and with the specified rounding
129    /// mode. The base's exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by
130    /// value. An [`Ordering`] is also returned, indicating whether the rounded value is less than,
131    /// equal to, or greater than the exact value. Although `NaN`s are not comparable to any
132    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
133    ///
134    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
135    ///
136    /// See [`RoundingMode`] for a description of the possible rounding modes.
137    ///
138    /// $$
139    /// f(x,k,p,m) = \log_{2^k}(1+x)+\varepsilon.
140    /// $$
141    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
142    ///   to be 0.
143    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon|
144    ///   < 2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p+1}$.
145    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
146    ///   2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p}$.
147    ///
148    /// If the output has a precision, it is `prec`.
149    ///
150    /// Special cases:
151    /// - $f(\text{NaN},k,p,m)=\text{NaN}$
152    /// - $f(\infty,k,p,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
153    /// - $f(-\infty,k,p,m)=\text{NaN}$
154    /// - $f(0.0,k,p,m)=0.0$ if $k>0$, and $-0.0$ if $k<0$
155    /// - $f(-0.0,k,p,m)=-0.0$ if $k>0$, and $0.0$ if $k<0$
156    /// - $f(-1.0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
157    /// - $f(x,k,p,m)=\text{NaN}$ for $x<-1$
158    /// - $f(x,k,p,m)=m/k$ when $1+x=2^m$, rounded to precision $p$; the result is exact if and only
159    ///   if $m/k$ is representable with precision $p$ (for example $\log_4 8=3/2$ when $x=7$ is
160    ///   exact, but $\log_8 4=2/3$ when $x=3$ is not)
161    ///
162    /// This function cannot overflow, but it can underflow:
163    /// - If $0<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
164    /// - If $0<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
165    ///   instead.
166    /// - If $0<f(x,k,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
167    /// - If $2^{-2^{30}-1}<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
168    ///   instead.
169    /// - If $-2^{-2^{30}}<f(x,k,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
170    ///   instead.
171    /// - If $-2^{-2^{30}}<f(x,k,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
172    ///   instead.
173    /// - If $-2^{-2^{30}-1}\leq f(x,k,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
174    /// - If $-2^{-2^{30}}<f(x,k,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
175    ///   returned instead.
176    ///
177    /// If you know you'll be using `Nearest`, consider using
178    /// [`Float::log_base_power_of_2_1_plus_x_prec`] instead. If you know that your target precision
179    /// is the precision of the input, consider using [`Float::log_base_power_of_2_1_plus_x_round`]
180    /// instead. If both of these things are true, consider using
181    /// [`Float::log_base_power_of_2_1_plus_x`] instead.
182    ///
183    /// # Worst-case complexity
184    /// $T(n) = O(n (\log n)^2 \log\log n)$
185    ///
186    /// $M(n) = O(n (\log n)^2)$
187    ///
188    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
189    ///
190    /// # Panics
191    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
192    /// is `Exact` but the result cannot be represented exactly with the given precision.
193    ///
194    /// # Examples
195    /// ```
196    /// use malachite_base::rounding_modes::RoundingMode::*;
197    /// use malachite_float::Float;
198    /// use std::cmp::Ordering::*;
199    ///
200    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
201    ///     .0
202    ///     .log_base_power_of_2_1_plus_x_prec_round(2, 20, Floor);
203    /// assert_eq!(log.to_string(), "1.729715");
204    /// assert_eq!(o, Less);
205    ///
206    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
207    ///     .0
208    ///     .log_base_power_of_2_1_plus_x_prec_round(2, 20, Ceiling);
209    /// assert_eq!(log.to_string(), "1.729717");
210    /// assert_eq!(o, Greater);
211    /// ```
212    #[inline]
213    pub fn log_base_power_of_2_1_plus_x_prec_round(
214        self,
215        pow: i64,
216        prec: u64,
217        rm: RoundingMode,
218    ) -> (Self, Ordering) {
219        assert_ne!(prec, 0);
220        assert_ne!(pow, 0, "Cannot take base-1 logarithm");
221        match self {
222            Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
223            float_infinity!() => (
224                if pow > 0 {
225                    float_infinity!()
226                } else {
227                    float_negative_infinity!()
228                },
229                Equal,
230            ),
231            // log_{2^pow}(1 ± 0) = ±0, with the sign flipped when pow < 0
232            Self(Zero { .. }) => (if pow > 0 { self } else { -self }, Equal),
233            _ => log_base_power_of_2_1_plus_x_prec_round_normal(&self, pow, prec, rm),
234        }
235    }
236
237    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
238    /// integer $k$, rounding the result to the specified precision and with the specified rounding
239    /// mode. The base's exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by
240    /// reference. An [`Ordering`] is also returned, indicating whether the rounded value is less
241    /// than, equal to, or greater than the exact value. Although `NaN`s are not comparable to any
242    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
243    ///
244    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
245    ///
246    /// See [`RoundingMode`] for a description of the possible rounding modes.
247    ///
248    /// $$
249    /// f(x,k,p,m) = \log_{2^k}(1+x)+\varepsilon.
250    /// $$
251    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
252    ///   to be 0.
253    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon|
254    ///   < 2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p+1}$.
255    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
256    ///   2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p}$.
257    ///
258    /// If the output has a precision, it is `prec`.
259    ///
260    /// Special cases:
261    /// - $f(\text{NaN},k,p,m)=\text{NaN}$
262    /// - $f(\infty,k,p,m)=\infty$ if $k>0$, and $-\infty$ if $k<0$
263    /// - $f(-\infty,k,p,m)=\text{NaN}$
264    /// - $f(0.0,k,p,m)=0.0$ if $k>0$, and $-0.0$ if $k<0$
265    /// - $f(-0.0,k,p,m)=-0.0$ if $k>0$, and $0.0$ if $k<0$
266    /// - $f(-1.0,k,p,m)=-\infty$ if $k>0$, and $\infty$ if $k<0$
267    /// - $f(x,k,p,m)=\text{NaN}$ for $x<-1$
268    /// - $f(x,k,p,m)=m/k$ when $1+x=2^m$, rounded to precision $p$; the result is exact if and only
269    ///   if $m/k$ is representable with precision $p$ (for example $\log_4 8=3/2$ when $x=7$ is
270    ///   exact, but $\log_8 4=2/3$ when $x=3$ is not)
271    ///
272    /// This function cannot overflow, but it can underflow:
273    /// - If $0<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
274    /// - If $0<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
275    ///   instead.
276    /// - If $0<f(x,k,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
277    /// - If $2^{-2^{30}-1}<f(x,k,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
278    ///   instead.
279    /// - If $-2^{-2^{30}}<f(x,k,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
280    ///   instead.
281    /// - If $-2^{-2^{30}}<f(x,k,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
282    ///   instead.
283    /// - If $-2^{-2^{30}-1}\leq f(x,k,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
284    /// - If $-2^{-2^{30}}<f(x,k,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
285    ///   returned instead.
286    ///
287    /// If you know you'll be using `Nearest`, consider using
288    /// [`Float::log_base_power_of_2_1_plus_x_prec_ref`] instead. If you know that your target
289    /// precision is the precision of the input, consider using
290    /// [`Float::log_base_power_of_2_1_plus_x_round_ref`] instead. If both of these things are true,
291    /// consider using `(&Float).log_base_power_of_2_1_plus_x()` instead.
292    ///
293    /// # Worst-case complexity
294    /// $T(n) = O(n (\log n)^2 \log\log n)$
295    ///
296    /// $M(n) = O(n (\log n)^2)$
297    ///
298    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
299    ///
300    /// # Panics
301    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
302    /// is `Exact` but the result cannot be represented exactly with the given precision.
303    ///
304    /// # Examples
305    /// ```
306    /// use malachite_base::rounding_modes::RoundingMode::*;
307    /// use malachite_float::Float;
308    /// use std::cmp::Ordering::*;
309    ///
310    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
311    ///     .0
312    ///     .log_base_power_of_2_1_plus_x_prec_round_ref(2, 20, Floor);
313    /// assert_eq!(log.to_string(), "1.729715");
314    /// assert_eq!(o, Less);
315    ///
316    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
317    ///     .0
318    ///     .log_base_power_of_2_1_plus_x_prec_round_ref(2, 20, Ceiling);
319    /// assert_eq!(log.to_string(), "1.729717");
320    /// assert_eq!(o, Greater);
321    /// ```
322    #[inline]
323    pub fn log_base_power_of_2_1_plus_x_prec_round_ref(
324        &self,
325        pow: i64,
326        prec: u64,
327        rm: RoundingMode,
328    ) -> (Self, Ordering) {
329        assert_ne!(prec, 0);
330        assert_ne!(pow, 0, "Cannot take base-1 logarithm");
331        match self {
332            Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
333            float_infinity!() => (
334                if pow > 0 {
335                    float_infinity!()
336                } else {
337                    float_negative_infinity!()
338                },
339                Equal,
340            ),
341            // log_{2^pow}(1 ± 0) = ±0, with the sign flipped when pow < 0
342            Self(Zero { .. }) => (if pow > 0 { self.clone() } else { -self }, Equal),
343            _ => log_base_power_of_2_1_plus_x_prec_round_normal(self, pow, prec, rm),
344        }
345    }
346
347    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
348    /// integer $k$, rounding the result to the nearest value of the specified precision. The base's
349    /// exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by value. An
350    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
351    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
352    /// whenever this function returns a `NaN` it also returns `Equal`.
353    ///
354    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
355    ///
356    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
357    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
358    /// description of the `Nearest` rounding mode.
359    ///
360    /// $$
361    /// f(x,k,p) = \log_{2^k}(1+x)+\varepsilon.
362    /// $$
363    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
364    ///   to be 0.
365    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
366    ///   |\log_{2^k}(1+x)|\rfloor-p}$.
367    ///
368    /// If the output has a precision, it is `prec`.
369    ///
370    /// Special cases:
371    /// - $f(\text{NaN},k,p)=\text{NaN}$
372    /// - $f(\infty,k,p)=\infty$ if $k>0$, and $-\infty$ if $k<0$
373    /// - $f(-\infty,k,p)=\text{NaN}$
374    /// - $f(0.0,k,p)=0.0$ if $k>0$, and $-0.0$ if $k<0$
375    /// - $f(-0.0,k,p)=-0.0$ if $k>0$, and $0.0$ if $k<0$
376    /// - $f(-1.0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
377    /// - $f(x,k,p)=\text{NaN}$ for $x<-1$
378    /// - $f(x,k,p)=m/k$ when $1+x=2^m$, rounded to precision $p$; the result is exact if and only
379    ///   if $m/k$ is representable with precision $p$
380    ///
381    /// This function cannot overflow, but it can underflow:
382    /// - If $0<f(x,k,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
383    /// - If $2^{-2^{30}-1}<f(x,k,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
384    /// - If $-2^{-2^{30}-1}\leq f(x,k,p)<0$, $-0.0$ is returned instead.
385    /// - If $-2^{-2^{30}}<f(x,k,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
386    ///
387    /// If you want to use a rounding mode other than `Nearest`, consider using
388    /// [`Float::log_base_power_of_2_1_plus_x_prec_round`] instead. If you know that your target
389    /// precision is the precision of the input, consider using
390    /// [`Float::log_base_power_of_2_1_plus_x`] instead.
391    ///
392    /// # Worst-case complexity
393    /// $T(n) = O(n (\log n)^2 \log\log n)$
394    ///
395    /// $M(n) = O(n (\log n)^2)$
396    ///
397    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
398    ///
399    /// # Panics
400    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
401    ///
402    /// # Examples
403    /// ```
404    /// use malachite_float::Float;
405    /// use std::cmp::Ordering::*;
406    ///
407    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
408    ///     .0
409    ///     .log_base_power_of_2_1_plus_x_prec(2, 20);
410    /// assert_eq!(log.to_string(), "1.729715");
411    /// assert_eq!(o, Less);
412    /// ```
413    #[inline]
414    pub fn log_base_power_of_2_1_plus_x_prec(self, pow: i64, prec: u64) -> (Self, Ordering) {
415        self.log_base_power_of_2_1_plus_x_prec_round(pow, prec, Nearest)
416    }
417
418    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
419    /// integer $k$, rounding the result to the nearest value of the specified precision. The base's
420    /// exponent $k$ is `pow`, which may be negative. The [`Float`] is taken by reference. An
421    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
422    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
423    /// whenever this function returns a `NaN` it also returns `Equal`.
424    ///
425    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
426    ///
427    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
428    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
429    /// description of the `Nearest` rounding mode.
430    ///
431    /// $$
432    /// f(x,k,p) = \log_{2^k}(1+x)+\varepsilon.
433    /// $$
434    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
435    ///   to be 0.
436    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
437    ///   |\log_{2^k}(1+x)|\rfloor-p}$.
438    ///
439    /// If the output has a precision, it is `prec`.
440    ///
441    /// Special cases:
442    /// - $f(\text{NaN},k,p)=\text{NaN}$
443    /// - $f(\infty,k,p)=\infty$ if $k>0$, and $-\infty$ if $k<0$
444    /// - $f(-\infty,k,p)=\text{NaN}$
445    /// - $f(0.0,k,p)=0.0$ if $k>0$, and $-0.0$ if $k<0$
446    /// - $f(-0.0,k,p)=-0.0$ if $k>0$, and $0.0$ if $k<0$
447    /// - $f(-1.0,k,p)=-\infty$ if $k>0$, and $\infty$ if $k<0$
448    /// - $f(x,k,p)=\text{NaN}$ for $x<-1$
449    /// - $f(x,k,p)=m/k$ when $1+x=2^m$, rounded to precision $p$; the result is exact if and only
450    ///   if $m/k$ is representable with precision $p$
451    ///
452    /// This function cannot overflow, but it can underflow:
453    /// - If $0<f(x,k,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
454    /// - If $2^{-2^{30}-1}<f(x,k,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
455    /// - If $-2^{-2^{30}-1}\leq f(x,k,p)<0$, $-0.0$ is returned instead.
456    /// - If $-2^{-2^{30}}<f(x,k,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
457    ///
458    /// If you want to use a rounding mode other than `Nearest`, consider using
459    /// [`Float::log_base_power_of_2_1_plus_x_prec_round_ref`] instead. If you know that your target
460    /// precision is the precision of the input, consider using
461    /// `(&Float).log_base_power_of_2_1_plus_x()` instead.
462    ///
463    /// # Worst-case complexity
464    /// $T(n) = O(n (\log n)^2 \log\log n)$
465    ///
466    /// $M(n) = O(n (\log n)^2)$
467    ///
468    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
469    ///
470    /// # Panics
471    /// Panics if `prec` is zero or if `pow` is zero (the base $2^0=1$ has no logarithm).
472    ///
473    /// # Examples
474    /// ```
475    /// use malachite_float::Float;
476    /// use std::cmp::Ordering::*;
477    ///
478    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
479    ///     .0
480    ///     .log_base_power_of_2_1_plus_x_prec_ref(2, 20);
481    /// assert_eq!(log.to_string(), "1.729715");
482    /// assert_eq!(o, Less);
483    /// ```
484    #[inline]
485    pub fn log_base_power_of_2_1_plus_x_prec_ref(&self, pow: i64, prec: u64) -> (Self, Ordering) {
486        self.log_base_power_of_2_1_plus_x_prec_round_ref(pow, prec, Nearest)
487    }
488
489    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
490    /// integer $k$, rounding the result with the specified rounding mode. The base's exponent $k$
491    /// is `pow`, which may be negative. The [`Float`] is taken by value. An [`Ordering`] is also
492    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
493    /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
494    /// returns a `NaN` it also returns `Equal`.
495    ///
496    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
497    ///
498    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
499    /// description of the possible rounding modes.
500    ///
501    /// $$
502    /// f(x,k,m) = \log_{2^k}(1+x)+\varepsilon.
503    /// $$
504    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
505    ///   to be 0.
506    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon|
507    ///   < 2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p+1}$, where $p$ is the precision of the
508    ///   input.
509    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
510    ///   2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
511    ///
512    /// If the output has a precision, it is the precision of the input.
513    ///
514    /// See the [`Float::log_base_power_of_2_1_plus_x_prec_round`] documentation for information on
515    /// special cases, overflow, and underflow.
516    ///
517    /// If you want to specify an output precision, consider using
518    /// [`Float::log_base_power_of_2_1_plus_x_prec_round`] instead. If you know you'll be using the
519    /// `Nearest` rounding mode, consider using [`Float::log_base_power_of_2_1_plus_x`] instead.
520    ///
521    /// # Worst-case complexity
522    /// $T(n) = O(n (\log n)^2 \log\log n)$
523    ///
524    /// $M(n) = O(n (\log n)^2)$
525    ///
526    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
527    ///
528    /// # Panics
529    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
530    /// result cannot be represented exactly with the input precision.
531    ///
532    /// # Examples
533    /// ```
534    /// use malachite_base::rounding_modes::RoundingMode::*;
535    /// use malachite_float::Float;
536    /// use std::cmp::Ordering::*;
537    ///
538    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
539    ///     .0
540    ///     .log_base_power_of_2_1_plus_x_round(2, Floor);
541    /// assert_eq!(log.to_string(), "1.729715809318648628099681523362");
542    /// assert_eq!(o, Less);
543    /// ```
544    #[inline]
545    pub fn log_base_power_of_2_1_plus_x_round(
546        self,
547        pow: i64,
548        rm: RoundingMode,
549    ) -> (Self, Ordering) {
550        let prec = self.significant_bits();
551        self.log_base_power_of_2_1_plus_x_prec_round(pow, prec, rm)
552    }
553
554    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
555    /// integer $k$, rounding the result with the specified rounding mode. The base's exponent $k$
556    /// is `pow`, which may be negative. The [`Float`] is taken by reference. An [`Ordering`] is
557    /// also returned, indicating whether the rounded value is less than, equal to, or greater than
558    /// the exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
559    /// returns a `NaN` it also returns `Equal`.
560    ///
561    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
562    ///
563    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
564    /// description of the possible rounding modes.
565    ///
566    /// $$
567    /// f(x,k,m) = \log_{2^k}(1+x)+\varepsilon.
568    /// $$
569    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
570    ///   to be 0.
571    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon|
572    ///   < 2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p+1}$, where $p$ is the precision of the
573    ///   input.
574    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
575    ///   2^{\lfloor\log_2 |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
576    ///
577    /// If the output has a precision, it is the precision of the input.
578    ///
579    /// See the [`Float::log_base_power_of_2_1_plus_x_prec_round`] documentation for information on
580    /// special cases, overflow, and underflow.
581    ///
582    /// If you want to specify an output precision, consider using
583    /// [`Float::log_base_power_of_2_1_plus_x_prec_round_ref`] instead. If you know you'll be using
584    /// the `Nearest` rounding mode, consider using `(&Float).log_base_power_of_2_1_plus_x()`
585    /// instead.
586    ///
587    /// # Worst-case complexity
588    /// $T(n) = O(n (\log n)^2 \log\log n)$
589    ///
590    /// $M(n) = O(n (\log n)^2)$
591    ///
592    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
593    ///
594    /// # Panics
595    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
596    /// result cannot be represented exactly with the input precision.
597    ///
598    /// # Examples
599    /// ```
600    /// use malachite_base::rounding_modes::RoundingMode::*;
601    /// use malachite_float::Float;
602    /// use std::cmp::Ordering::*;
603    ///
604    /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
605    ///     .0
606    ///     .log_base_power_of_2_1_plus_x_round_ref(2, Floor);
607    /// assert_eq!(log.to_string(), "1.729715809318648628099681523362");
608    /// assert_eq!(o, Less);
609    /// ```
610    #[inline]
611    pub fn log_base_power_of_2_1_plus_x_round_ref(
612        &self,
613        pow: i64,
614        rm: RoundingMode,
615    ) -> (Self, Ordering) {
616        let prec = self.significant_bits();
617        self.log_base_power_of_2_1_plus_x_prec_round_ref(pow, prec, rm)
618    }
619
620    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
621    /// integer $k$, in place, rounding the result to the specified precision and with the specified
622    /// rounding mode. The base's exponent $k$ is `pow`, which may be negative. An [`Ordering`] is
623    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
624    /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
625    /// sets the [`Float`] to `NaN` it also returns `Equal`.
626    ///
627    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to
628    /// `NaN`.
629    ///
630    /// See [`RoundingMode`] for a description of the possible rounding modes.
631    ///
632    /// $$
633    /// x \gets \log_{2^k}(1+x)+\varepsilon.
634    /// $$
635    ///
636    /// If the output has a precision, it is `prec`.
637    ///
638    /// See the [`Float::log_base_power_of_2_1_plus_x_prec_round`] documentation for information on
639    /// special cases, overflow, and underflow.
640    ///
641    /// If you know you'll be using `Nearest`, consider using
642    /// [`Float::log_base_power_of_2_1_plus_x_prec_assign`] instead. If you know that your target
643    /// precision is the precision of the input, consider using
644    /// [`Float::log_base_power_of_2_1_plus_x_round_assign`] instead. If both of these things are
645    /// true, consider using [`Float::log_base_power_of_2_1_plus_x_assign`] instead.
646    ///
647    /// # Worst-case complexity
648    /// $T(n) = O(n (\log n)^2 \log\log n)$
649    ///
650    /// $M(n) = O(n (\log n)^2)$
651    ///
652    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
653    ///
654    /// # Panics
655    /// Panics if `prec` is zero, if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm`
656    /// is `Exact` but the result cannot be represented exactly with the given precision.
657    ///
658    /// # Examples
659    /// ```
660    /// use malachite_base::rounding_modes::RoundingMode::*;
661    /// use malachite_float::Float;
662    /// use std::cmp::Ordering::*;
663    ///
664    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
665    /// assert_eq!(
666    ///     x.log_base_power_of_2_1_plus_x_prec_round_assign(2, 20, Floor),
667    ///     Less
668    /// );
669    /// assert_eq!(x.to_string(), "1.729715");
670    /// ```
671    #[inline]
672    pub fn log_base_power_of_2_1_plus_x_prec_round_assign(
673        &mut self,
674        pow: i64,
675        prec: u64,
676        rm: RoundingMode,
677    ) -> Ordering {
678        let (result, o) =
679            core::mem::take(self).log_base_power_of_2_1_plus_x_prec_round(pow, prec, rm);
680        *self = result;
681        o
682    }
683
684    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
685    /// integer $k$, in place, rounding the result to the nearest value of the specified precision.
686    /// The base's exponent $k$ is `pow`, which may be negative. An [`Ordering`] is returned,
687    /// indicating whether the rounded value is less than, equal to, or greater than the exact
688    /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
689    /// [`Float`] to `NaN` it also returns `Equal`.
690    ///
691    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to
692    /// `NaN`.
693    ///
694    /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
695    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
696    /// description of the `Nearest` rounding mode.
697    ///
698    /// $$
699    /// x \gets \log_{2^k}(1+x)+\varepsilon.
700    /// $$
701    ///
702    /// If the output has a precision, it is `prec`.
703    ///
704    /// See the [`Float::log_base_power_of_2_1_plus_x_prec`] documentation for information on
705    /// special cases, overflow, and underflow.
706    ///
707    /// If you want to use a rounding mode other than `Nearest`, consider using
708    /// [`Float::log_base_power_of_2_1_plus_x_prec_round_assign`] instead. If you know that your
709    /// target precision is the precision of the input, consider using
710    /// [`Float::log_base_power_of_2_1_plus_x_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 or if `pow` is zero (the base $2^0=1$ has no logarithm).
721    ///
722    /// # Examples
723    /// ```
724    /// use malachite_float::Float;
725    /// use std::cmp::Ordering::*;
726    ///
727    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
728    /// assert_eq!(x.log_base_power_of_2_1_plus_x_prec_assign(2, 20), Less);
729    /// assert_eq!(x.to_string(), "1.729715");
730    /// ```
731    #[inline]
732    pub fn log_base_power_of_2_1_plus_x_prec_assign(&mut self, pow: i64, prec: u64) -> Ordering {
733        self.log_base_power_of_2_1_plus_x_prec_round_assign(pow, prec, Nearest)
734    }
735
736    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
737    /// integer $k$, in place, rounding the result with the specified rounding mode. The base's
738    /// exponent $k$ is `pow`, which may be negative. An [`Ordering`] is returned, indicating
739    /// whether the rounded value is less than, equal to, or greater than the exact value. Although
740    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
741    /// `NaN` it also returns `Equal`.
742    ///
743    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to
744    /// `NaN`.
745    ///
746    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
747    /// description of the possible rounding modes.
748    ///
749    /// $$
750    /// x \gets \log_{2^k}(1+x)+\varepsilon.
751    /// $$
752    ///
753    /// If the output has a precision, it is the precision of the input.
754    ///
755    /// See the [`Float::log_base_power_of_2_1_plus_x_round`] documentation for information on
756    /// special cases, overflow, and underflow.
757    ///
758    /// If you want to specify an output precision, consider using
759    /// [`Float::log_base_power_of_2_1_plus_x_prec_round_assign`] instead. If you know you'll be
760    /// using the `Nearest` rounding mode, consider using
761    /// [`Float::log_base_power_of_2_1_plus_x_assign`] instead.
762    ///
763    /// # Worst-case complexity
764    /// $T(n) = O(n (\log n)^2 \log\log n)$
765    ///
766    /// $M(n) = O(n (\log n)^2)$
767    ///
768    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
769    ///
770    /// # Panics
771    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm), or if `rm` is `Exact` but the
772    /// result cannot be represented exactly with the input precision.
773    ///
774    /// # Examples
775    /// ```
776    /// use malachite_base::rounding_modes::RoundingMode::*;
777    /// use malachite_float::Float;
778    /// use std::cmp::Ordering::*;
779    ///
780    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
781    /// assert_eq!(x.log_base_power_of_2_1_plus_x_round_assign(2, Floor), Less);
782    /// assert_eq!(x.to_string(), "1.729715809318648628099681523362");
783    /// ```
784    #[inline]
785    pub fn log_base_power_of_2_1_plus_x_round_assign(
786        &mut self,
787        pow: i64,
788        rm: RoundingMode,
789    ) -> Ordering {
790        let prec = self.significant_bits();
791        self.log_base_power_of_2_1_plus_x_prec_round_assign(pow, prec, rm)
792    }
793}
794
795impl LogBasePowerOf2Of1PlusX<i64> for Float {
796    type Output = Self;
797
798    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
799    /// integer $k$, taking it by value. The base's exponent $k$ is `pow`, which may be negative.
800    ///
801    /// If the output has a precision, it is the precision of the input. If the logarithm is
802    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
803    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
804    /// rounding mode.
805    ///
806    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
807    ///
808    /// $$
809    /// f(x,k) = \log_{2^k}(1+x)+\varepsilon.
810    /// $$
811    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
812    ///   to be 0.
813    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
814    ///   |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
815    ///
816    /// See the [`Float::log_base_power_of_2_1_plus_x_prec_round`] documentation for information on
817    /// special cases, overflow, and underflow.
818    ///
819    /// If you want to use a rounding mode other than `Nearest`, consider using
820    /// [`Float::log_base_power_of_2_1_plus_x_round`] instead. If you want to specify the output
821    /// precision, consider using [`Float::log_base_power_of_2_1_plus_x_prec`]. If you want both of
822    /// these things, consider using [`Float::log_base_power_of_2_1_plus_x_prec_round`].
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 `self.get_prec()`.
830    ///
831    /// # Panics
832    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
833    ///
834    /// # Examples
835    /// ```
836    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2Of1PlusX;
837    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
838    /// use malachite_float::Float;
839    ///
840    /// assert!(Float::NAN.log_base_power_of_2_1_plus_x(2).is_nan());
841    /// assert_eq!(
842    ///     Float::INFINITY.log_base_power_of_2_1_plus_x(2),
843    ///     Float::INFINITY
844    /// );
845    /// assert!(Float::NEGATIVE_INFINITY
846    ///     .log_base_power_of_2_1_plus_x(2)
847    ///     .is_nan());
848    /// assert_eq!(
849    ///     Float::from_unsigned_prec(10u32, 100)
850    ///         .0
851    ///         .log_base_power_of_2_1_plus_x(2)
852    ///         .to_string(),
853    ///     "1.729715809318648628099681523362"
854    /// );
855    /// ```
856    #[inline]
857    fn log_base_power_of_2_1_plus_x(self, pow: i64) -> Self {
858        let prec = self.significant_bits();
859        self.log_base_power_of_2_1_plus_x_prec_round(pow, prec, Nearest)
860            .0
861    }
862}
863
864impl LogBasePowerOf2Of1PlusX<i64> for &Float {
865    type Output = Float;
866
867    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
868    /// integer $k$, taking it by reference. The base's exponent $k$ is `pow`, which may be
869    /// negative.
870    ///
871    /// If the output has a precision, it is the precision of the input. If the logarithm is
872    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
873    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
874    /// rounding mode.
875    ///
876    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
877    ///
878    /// $$
879    /// f(x,k) = \log_{2^k}(1+x)+\varepsilon.
880    /// $$
881    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
882    ///   to be 0.
883    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
884    ///   |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
885    ///
886    /// See the [`Float::log_base_power_of_2_1_plus_x_prec_round`] documentation for information on
887    /// special cases, overflow, and underflow.
888    ///
889    /// If you want to use a rounding mode other than `Nearest`, consider using
890    /// [`Float::log_base_power_of_2_1_plus_x_round_ref`] instead. If you want to specify the output
891    /// precision, consider using [`Float::log_base_power_of_2_1_plus_x_prec_ref`]. If you want both
892    /// of these things, consider using [`Float::log_base_power_of_2_1_plus_x_prec_round_ref`].
893    ///
894    /// # Worst-case complexity
895    /// $T(n) = O(n (\log n)^2 \log\log n)$
896    ///
897    /// $M(n) = O(n (\log n)^2)$
898    ///
899    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
900    ///
901    /// # Panics
902    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
903    ///
904    /// # Examples
905    /// ```
906    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2Of1PlusX;
907    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
908    /// use malachite_float::Float;
909    ///
910    /// assert!((&Float::NAN).log_base_power_of_2_1_plus_x(2).is_nan());
911    /// assert_eq!(
912    ///     (&Float::INFINITY).log_base_power_of_2_1_plus_x(2),
913    ///     Float::INFINITY
914    /// );
915    /// assert!((&Float::NEGATIVE_INFINITY)
916    ///     .log_base_power_of_2_1_plus_x(2)
917    ///     .is_nan());
918    /// assert_eq!(
919    ///     (&Float::from_unsigned_prec(10u32, 100).0)
920    ///         .log_base_power_of_2_1_plus_x(2)
921    ///         .to_string(),
922    ///     "1.729715809318648628099681523362"
923    /// );
924    /// ```
925    #[inline]
926    fn log_base_power_of_2_1_plus_x(self, pow: i64) -> Float {
927        let prec = self.significant_bits();
928        self.log_base_power_of_2_1_plus_x_prec_round_ref(pow, prec, Nearest)
929            .0
930    }
931}
932
933impl LogBasePowerOf2Of1PlusXAssign<i64> for Float {
934    /// Computes $\log_{2^k}(1+x)$, where $x$ is a [`Float`] and the base is $2^k$ for some nonzero
935    /// integer $k$, in place. The base's exponent $k$ is `pow`, which may be negative.
936    ///
937    /// If the output has a precision, it is the precision of the input. If the logarithm is
938    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
939    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
940    /// rounding mode.
941    ///
942    /// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to
943    /// `NaN`.
944    ///
945    /// $$
946    /// x \gets \log_{2^k}(1+x)+\varepsilon.
947    /// $$
948    /// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
949    ///   to be 0.
950    /// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
951    ///   |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
952    ///
953    /// See the [`Float::log_base_power_of_2_1_plus_x`] documentation for information on special
954    /// cases, overflow, and underflow.
955    ///
956    /// If you want to use a rounding mode other than `Nearest`, consider using
957    /// [`Float::log_base_power_of_2_1_plus_x_round_assign`] instead. If you want to specify the
958    /// output precision, consider using [`Float::log_base_power_of_2_1_plus_x_prec_assign`]. If you
959    /// want both of these things, consider using
960    /// [`Float::log_base_power_of_2_1_plus_x_prec_round_assign`].
961    ///
962    /// # Worst-case complexity
963    /// $T(n) = O(n (\log n)^2 \log\log n)$
964    ///
965    /// $M(n) = O(n (\log n)^2)$
966    ///
967    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
968    ///
969    /// # Panics
970    /// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
971    ///
972    /// # Examples
973    /// ```
974    /// use malachite_base::num::arithmetic::traits::LogBasePowerOf2Of1PlusXAssign;
975    /// use malachite_base::num::basic::traits::{Infinity, NaN};
976    /// use malachite_float::Float;
977    ///
978    /// let mut x = Float::NAN;
979    /// x.log_base_power_of_2_1_plus_x_assign(2);
980    /// assert!(x.is_nan());
981    ///
982    /// let mut x = Float::INFINITY;
983    /// x.log_base_power_of_2_1_plus_x_assign(2);
984    /// assert_eq!(x, Float::INFINITY);
985    ///
986    /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
987    /// x.log_base_power_of_2_1_plus_x_assign(2);
988    /// assert_eq!(x.to_string(), "1.729715809318648628099681523362");
989    /// ```
990    #[inline]
991    fn log_base_power_of_2_1_plus_x_assign(&mut self, pow: i64) {
992        let prec = self.significant_bits();
993        self.log_base_power_of_2_1_plus_x_prec_round_assign(pow, prec, Nearest);
994    }
995}
996
997/// Computes $\log_{2^k}(1+x)$, the base-$2^k$ logarithm of one plus a primitive float, where the
998/// base is $2^k$ for some nonzero integer $k$. The exponent $k$ is `pow`, which may be negative.
999/// Using this function is more accurate than computing the logarithm using the standard library,
1000/// both because $1+x$ may not be representable as a primitive float and because the standard
1001/// library's `log2` is not always correctly rounded.
1002///
1003/// $\log_{2^k}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
1004///
1005/// $$
1006/// f(x,k) = \log_{2^k}(1+x)+\varepsilon.
1007/// $$
1008/// - If $\log_{2^k}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1009///   be 0.
1010/// - If $\log_{2^k}(1+x)$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1011///   |\log_{2^k}(1+x)|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a
1012///   [`f32`] and 53 if `T` is a [`f64`], but less if the output is subnormal).
1013///
1014/// Special cases:
1015/// - $f(\text{NaN},k)=\text{NaN}$
1016/// - $f(\infty,k)=\infty$ if $k>0$, and $-\infty$ if $k<0$
1017/// - $f(-\infty,k)=\text{NaN}$
1018/// - $f(0.0,k)=0.0$ if $k>0$, and $-0.0$ if $k<0$
1019/// - $f(-0.0,k)=-0.0$ if $k>0$, and $0.0$ if $k<0$
1020/// - $f(-1.0,k)=-\infty$ if $k>0$, and $\infty$ if $k<0$
1021/// - $f(x,k)=\text{NaN}$ for $x<-1$
1022///
1023/// This function can underflow (to a subnormal or zero) when $x$ is close to zero and $|k|$ is
1024/// large, but it cannot overflow.
1025///
1026/// # Worst-case complexity
1027/// Constant time and additional memory.
1028///
1029/// # Panics
1030/// Panics if `pow` is zero (the base $2^0=1$ has no logarithm).
1031///
1032/// # Examples
1033/// ```
1034/// use malachite_base::num::basic::traits::NegativeInfinity;
1035/// use malachite_base::num::float::NiceFloat;
1036/// use malachite_float::arithmetic::log_base_power_of_2_1_plus_x::*;
1037///
1038/// assert!(primitive_float_log_base_power_of_2_1_plus_x(f32::NAN, 2).is_nan());
1039/// assert_eq!(
1040///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(
1041///         f32::INFINITY,
1042///         2
1043///     )),
1044///     NiceFloat(f32::INFINITY)
1045/// );
1046/// assert_eq!(
1047///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(-1.0f32, 2)),
1048///     NiceFloat(f32::NEGATIVE_INFINITY)
1049/// );
1050/// assert!(primitive_float_log_base_power_of_2_1_plus_x(-2.0f32, 2).is_nan());
1051/// // log_4(1 + 15) = log_4(16) = 2
1052/// assert_eq!(
1053///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(15.0f32, 2)),
1054///     NiceFloat(2.0)
1055/// );
1056/// // log_4(1 + 7) = log_4(8) = 3/2
1057/// assert_eq!(
1058///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(7.0f32, 2)),
1059///     NiceFloat(1.5)
1060/// );
1061/// // log_8(1 + 63) = log_8(64) = 2
1062/// assert_eq!(
1063///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(63.0f32, 3)),
1064///     NiceFloat(2.0)
1065/// );
1066/// // log_4(1 + 9) = log_4(10)
1067/// assert_eq!(
1068///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(9.0f32, 2)),
1069///     NiceFloat(1.660964)
1070/// );
1071/// // log_(1/2)(1 + 7) = log_(1/2)(8) = -3
1072/// assert_eq!(
1073///     NiceFloat(primitive_float_log_base_power_of_2_1_plus_x(7.0f32, -1)),
1074///     NiceFloat(-3.0)
1075/// );
1076/// ```
1077#[inline]
1078#[allow(clippy::type_repetition_in_bounds)]
1079pub fn primitive_float_log_base_power_of_2_1_plus_x<T: PrimitiveFloat>(x: T, pow: i64) -> T
1080where
1081    Float: From<T> + PartialOrd<T>,
1082    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1083{
1084    emulate_float_to_float_fn(
1085        |x, prec| Float::log_base_power_of_2_1_plus_x_prec(x, pow, prec),
1086        x,
1087    )
1088}