Skip to main content

malachite_float/float/arithmetic/
log_base_10_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::float::arithmetic::log_base_1_plus_x::log_base_1_plus_x_rational;
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, LogBase10Of1PlusX, LogBase10Of1PlusXAssign,
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::round::float_can_round;
23use malachite_nz::platform::Limb;
24
25// The computation of log_base_10_1_plus_x(x) is done by log_10(1 + x) = log_2(1 + x) / log_2(10).
26// The input is finite and greater than -1.
27//
28// This specializes `log_base_1_plus_x` to base 10. Like that function (and unlike the plain
29// `log_base_10`), it routes through `log_base_2_1_plus_x` rather than computing `log_10(1 + x)`
30// from `1 + x` directly, preserving accuracy when x is near 0 where `1 + x` would lose precision.
31// Since 10 = 2 * 5 is not a perfect power, `log_10(1 + x)` is rational only when `1 + x = 10^m` (m
32// a nonnegative integer, so x = 0 or x = 10^m - 1); those exact results are detected up front (the
33// Ziv loop could never certify an exactly-representable one). `log_2(10)` is irrational, so every
34// other result is strictly between `Float`s and the loop converges.
35fn log_base_10_1_plus_x_prec_round_normal(
36    x: &Float,
37    prec: u64,
38    rm: RoundingMode,
39) -> (Float, Ordering) {
40    // log_10(1 + x) is undefined for x < -1.
41    match x.partial_cmp(&-1i32).unwrap() {
42        // 1 + x = 0, so log_10(1 + x) = -infinity.
43        Equal => return (float_negative_infinity!(), Equal),
44        Less => return (float_nan!(), Equal),
45        _ => {}
46    }
47    // If 1 + x = 10^m, then log_10(1 + x) = m is rational and exact. `log_base_1_plus_x_rational`
48    // with base 10 returns `Some(m / 1)`.
49    if let Some(q) = log_base_1_plus_x_rational(x, 10) {
50        return Float::from_rational_prec_round(q, prec, rm);
51    }
52    // The result is irrational, so it is never exactly representable.
53    assert_ne!(rm, Exact, "Inexact log_base_10_1_plus_x");
54    const TEN: Float = Float::const_from_unsigned(10);
55    let min_exp = Float::MIN_EXPONENT_I64;
56    let mut working_prec = prec + 4 + prec.ceiling_log_base_2();
57    let mut increment = Limb::WIDTH;
58    loop {
59        // log_2(1 + x), correctly rounded to working_prec; always within the Float exponent range.
60        let num = x.log_base_2_1_plus_x_prec_ref(working_prec).0;
61        // log_2(10) > 1, correctly rounded to working_prec.
62        let den = TEN.log_base_2_prec(working_prec).0;
63        // Dividing by log_2(10) > 1 only shrinks the magnitude (overflow is impossible), but can
64        // push the result below MIN_EXPONENT. When it underflows, the Ziv test below could never
65        // resolve it (the quotient clamps), so hand the rounding to div_prec_round, which clamps to
66        // zero or the minimum positive value per the rounding mode. The exact quotient exponent is
67        // only resolved in the narrow band where the cheap exponent bound is inconclusive (then
68        // e_num - e_den == min_exp - 1, so the result underflows iff |log_2(1 + x)| * 2^(1 -
69        // min_exp) < log_2(10)). The left shift only adjusts the exponent, avoiding a huge Rational
70        // conversion.
71        let e_num = i64::from(num.get_exponent().unwrap());
72        let e_den = i64::from(den.get_exponent().unwrap());
73        if e_num - e_den + 1 < min_exp
74            || (e_num - e_den < min_exp && (&num << u64::exact_from(1 - min_exp)).lt_abs(&den))
75        {
76            return num.div_prec_round(den, prec, rm);
77        }
78        // log_2(1 + x) / log_2(10), with three correctly-rounded operations (log_base_2_1_plus_x,
79        // log_base_2, and the division, each at most 1/2 ulp), so the relative error is below 2^(2
80        // - working_prec) and working_prec - 4 correct bits suffice for rounding.
81        let t = num / den;
82        if float_can_round(t.significand_ref().unwrap(), working_prec - 4, prec, rm) {
83            return Float::from_float_prec_round(t, prec, rm);
84        }
85        // Increase the precision.
86        working_prec += increment;
87        increment = working_prec >> 1;
88    }
89}
90
91impl Float {
92    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the specified
93    /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
94    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
95    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
96    /// whenever this function returns a `NaN` it also returns `Equal`.
97    ///
98    /// $\log_{10}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
99    ///
100    /// This computes $\log_2(1+x) / \log_2 10$, preserving accuracy for $x$ near 0.
101    ///
102    /// See [`RoundingMode`] for a description of the possible rounding modes.
103    ///
104    /// $$
105    /// f(x,p,m) = \log_{10}(1+x)+\varepsilon.
106    /// $$
107    /// - If $\log_{10}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed
108    ///   to be 0.
109    /// - If $\log_{10}(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
110    ///   2^{\lfloor\log_2 |\log_{10}(1+x)|\rfloor-p+1}$.
111    /// - If $\log_{10}(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
112    ///   2^{\lfloor\log_2 |\log_{10}(1+x)|\rfloor-p}$.
113    ///
114    /// If the output has a precision, it is `prec`.
115    ///
116    /// Special cases:
117    /// - $f(\text{NaN},p,m)=\text{NaN}$
118    /// - $f(\infty,p,m)=\infty$
119    /// - $f(-\infty,p,m)=\text{NaN}$
120    /// - $f(\pm0.0,p,m)=\pm0.0$
121    /// - $f(-1.0,p,m)=-\infty$
122    /// - $f(x,p,m)=\text{NaN}$ for $x<-1$
123    /// - $f(x,p,m)=m$ when $1+x=10^m$, rounded to precision $p$; the result is exact if and only if
124    ///   $m$ is representable with precision $p$ (for example $\log_{10}(1+9)=1$ when $x=9$ is
125    ///   exact)
126    ///
127    /// This function cannot overflow, but it can underflow.
128    ///
129    /// If you know you'll be using `Nearest`, consider using [`Float::log_base_10_1_plus_x_prec`]
130    /// instead. If you know that your target precision is the precision of the input, consider
131    /// using [`Float::log_base_10_1_plus_x_round`] instead. If both of these things are true,
132    /// consider using `(&Float).log_base_10_1_plus_x()` instead.
133    ///
134    /// # Worst-case complexity
135    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
136    ///
137    /// $M(n, m) = O(n \log n + m \log m)$
138    ///
139    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
140    /// `self.significant_bits()`.
141    ///
142    /// # Panics
143    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
144    /// with the given precision.
145    ///
146    /// # Examples
147    /// ```
148    /// use malachite_base::num::basic::traits::One;
149    /// use malachite_base::rounding_modes::RoundingMode::*;
150    /// use malachite_float::Float;
151    /// use std::cmp::Ordering::*;
152    ///
153    /// let (log, o) = Float::from(9).log_base_10_1_plus_x_prec_round(10, Exact);
154    /// assert_eq!(log.to_string(), "1.0000"); // log_10(10) = 1
155    /// assert_eq!(o, Equal);
156    ///
157    /// let (log, o) = Float::ONE.log_base_10_1_plus_x_prec_round(20, Nearest);
158    /// assert_eq!(log.to_string(), "0.30103016"); // log_10(2)
159    /// assert_eq!(o, Greater);
160    /// ```
161    #[inline]
162    pub fn log_base_10_1_plus_x_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
163        assert_ne!(prec, 0);
164        match self {
165            Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
166            float_infinity!() => (float_infinity!(), Equal),
167            Self(Zero { .. }) => (self, Equal),
168            _ => log_base_10_1_plus_x_prec_round_normal(&self, prec, rm),
169        }
170    }
171
172    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the specified
173    /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
174    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
175    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
176    /// whenever this function returns a `NaN` it also returns `Equal`.
177    ///
178    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details, special cases, and a description
179    /// of the rounding behavior.
180    ///
181    /// # Worst-case complexity
182    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
183    ///
184    /// $M(n, m) = O(n \log n + m \log m)$
185    ///
186    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
187    /// `self.significant_bits()`.
188    ///
189    /// # Panics
190    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
191    /// with the given precision.
192    ///
193    /// # Examples
194    /// ```
195    /// use malachite_base::num::basic::traits::One;
196    /// use malachite_base::rounding_modes::RoundingMode::*;
197    /// use malachite_float::Float;
198    /// use std::cmp::Ordering::*;
199    ///
200    /// let (log, o) = (&Float::from(99)).log_base_10_1_plus_x_prec_round_ref(10, Exact);
201    /// assert_eq!(log.to_string(), "2.0000"); // log_10(100) = 2
202    /// assert_eq!(o, Equal);
203    ///
204    /// let (log, o) = (&Float::ONE).log_base_10_1_plus_x_prec_round_ref(20, Floor);
205    /// assert_eq!(log.to_string(), "0.30102968"); // log_10(2), rounded down
206    /// assert_eq!(o, Less);
207    /// ```
208    #[inline]
209    pub fn log_base_10_1_plus_x_prec_round_ref(
210        &self,
211        prec: u64,
212        rm: RoundingMode,
213    ) -> (Self, Ordering) {
214        assert_ne!(prec, 0);
215        match self {
216            Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
217            float_infinity!() => (float_infinity!(), Equal),
218            Self(Zero { .. }) => (self.clone(), Equal),
219            _ => log_base_10_1_plus_x_prec_round_normal(self, prec, rm),
220        }
221    }
222
223    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest
224    /// value of the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also
225    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
226    /// exact value.
227    ///
228    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
229    ///
230    /// # Worst-case complexity
231    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
232    ///
233    /// $M(n, m) = O(n \log n + m \log m)$
234    ///
235    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
236    /// `self.significant_bits()`.
237    ///
238    /// # Panics
239    /// Panics if `prec` is zero.
240    ///
241    /// # Examples
242    /// ```
243    /// use malachite_base::num::basic::traits::One;
244    /// use malachite_float::Float;
245    /// use std::cmp::Ordering::*;
246    ///
247    /// let (log, o) = Float::from(9).log_base_10_1_plus_x_prec(10);
248    /// assert_eq!(log.to_string(), "1.0000"); // log_10(10) = 1
249    /// assert_eq!(o, Equal);
250    ///
251    /// let (log, o) = Float::ONE.log_base_10_1_plus_x_prec(20);
252    /// assert_eq!(log.to_string(), "0.30103016"); // log_10(2)
253    /// assert_eq!(o, Greater);
254    /// ```
255    #[inline]
256    pub fn log_base_10_1_plus_x_prec(self, prec: u64) -> (Self, Ordering) {
257        self.log_base_10_1_plus_x_prec_round(prec, Nearest)
258    }
259
260    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest
261    /// value of the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is
262    /// also returned, indicating whether the rounded value is less than, equal to, or greater than
263    /// the exact value.
264    ///
265    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
266    ///
267    /// # Worst-case complexity
268    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
269    ///
270    /// $M(n, m) = O(n \log n + m \log m)$
271    ///
272    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
273    /// `self.significant_bits()`.
274    ///
275    /// # Panics
276    /// Panics if `prec` is zero.
277    ///
278    /// # Examples
279    /// ```
280    /// use malachite_float::Float;
281    /// use std::cmp::Ordering::*;
282    ///
283    /// let (log, o) = (&Float::from(99)).log_base_10_1_plus_x_prec_ref(10);
284    /// assert_eq!(log.to_string(), "2.0000"); // log_10(100) = 2
285    /// assert_eq!(o, Equal);
286    ///
287    /// let (log, o) = (&Float::from(7)).log_base_10_1_plus_x_prec_ref(30);
288    /// assert_eq!(log.to_string(), "0.90308998711"); // log_10(8)
289    /// assert_eq!(o, Greater);
290    /// ```
291    #[inline]
292    pub fn log_base_10_1_plus_x_prec_ref(&self, prec: u64) -> (Self, Ordering) {
293        self.log_base_10_1_plus_x_prec_round_ref(prec, Nearest)
294    }
295
296    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the precision of
297    /// the input and with the specified rounding mode. The [`Float`] is taken by value. An
298    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
299    /// or greater than the exact value.
300    ///
301    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
302    ///
303    /// # Worst-case complexity
304    /// $T(n) = O(n (\log n)^2 \log\log n)$
305    ///
306    /// $M(n) = O(n \log n)$
307    ///
308    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
309    ///
310    /// # Panics
311    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
312    /// precision.
313    ///
314    /// # Examples
315    /// ```
316    /// use malachite_base::rounding_modes::RoundingMode::*;
317    /// use malachite_float::Float;
318    /// use std::cmp::Ordering::*;
319    ///
320    /// let (log, o) = Float::from(9).log_base_10_1_plus_x_round(Exact);
321    /// assert_eq!(log.to_string(), "1.00"); // log_10(10) = 1
322    /// assert_eq!(o, Equal);
323    ///
324    /// let (log, o) = Float::from(99).log_base_10_1_plus_x_round(Exact);
325    /// assert_eq!(log.to_string(), "2.000"); // log_10(100) = 2
326    /// assert_eq!(o, Equal);
327    /// ```
328    #[inline]
329    pub fn log_base_10_1_plus_x_round(self, rm: RoundingMode) -> (Self, Ordering) {
330        let prec = self.significant_bits();
331        self.log_base_10_1_plus_x_prec_round(prec, rm)
332    }
333
334    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the precision of
335    /// the input and with the specified rounding mode. The [`Float`] is taken by reference. An
336    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
337    /// or greater than the exact value.
338    ///
339    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
340    ///
341    /// # Worst-case complexity
342    /// $T(n) = O(n (\log n)^2 \log\log n)$
343    ///
344    /// $M(n) = O(n \log n)$
345    ///
346    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
347    ///
348    /// # Panics
349    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
350    /// precision.
351    ///
352    /// # Examples
353    /// ```
354    /// use malachite_base::rounding_modes::RoundingMode::*;
355    /// use malachite_float::Float;
356    /// use std::cmp::Ordering::*;
357    ///
358    /// let (log, o) = (&Float::from(99)).log_base_10_1_plus_x_round_ref(Exact);
359    /// assert_eq!(log.to_string(), "2.000"); // log_10(100) = 2
360    /// assert_eq!(o, Equal);
361    ///
362    /// let (log, o) = (&Float::from(9)).log_base_10_1_plus_x_round_ref(Exact);
363    /// assert_eq!(log.to_string(), "1.00"); // log_10(10) = 1
364    /// assert_eq!(o, Equal);
365    /// ```
366    #[inline]
367    pub fn log_base_10_1_plus_x_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
368        self.log_base_10_1_plus_x_prec_round_ref(self.significant_bits(), rm)
369    }
370
371    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], in place, rounding the result to the
372    /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
373    /// indicating whether the rounded value is less than, equal to, or greater than the exact
374    /// value.
375    ///
376    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
377    ///
378    /// # Worst-case complexity
379    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
380    ///
381    /// $M(n, m) = O(n \log n + m \log m)$
382    ///
383    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
384    /// `self.significant_bits()`.
385    ///
386    /// # Panics
387    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
388    /// with the given precision.
389    ///
390    /// # Examples
391    /// ```
392    /// use malachite_base::num::basic::traits::One;
393    /// use malachite_base::rounding_modes::RoundingMode::*;
394    /// use malachite_float::Float;
395    /// use std::cmp::Ordering::*;
396    ///
397    /// let mut x = Float::from(9);
398    /// assert_eq!(x.log_base_10_1_plus_x_prec_round_assign(10, Exact), Equal);
399    /// assert_eq!(x.to_string(), "1.0000"); // log_10(10) = 1
400    ///
401    /// let mut x = Float::ONE;
402    /// assert_eq!(x.log_base_10_1_plus_x_prec_round_assign(20, Floor), Less);
403    /// assert_eq!(x.to_string(), "0.30102968"); // log_10(2), rounded down
404    /// ```
405    #[inline]
406    pub fn log_base_10_1_plus_x_prec_round_assign(
407        &mut self,
408        prec: u64,
409        rm: RoundingMode,
410    ) -> Ordering {
411        let (result, o) = core::mem::take(self).log_base_10_1_plus_x_prec_round(prec, rm);
412        *self = result;
413        o
414    }
415
416    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], in place, rounding the result to the
417    /// nearest value of the specified precision. An [`Ordering`] is returned, indicating whether
418    /// the rounded value is less than, equal to, or greater than the exact value.
419    ///
420    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
421    ///
422    /// # Worst-case complexity
423    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
424    ///
425    /// $M(n, m) = O(n \log n + m \log m)$
426    ///
427    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
428    /// `self.significant_bits()`.
429    ///
430    /// # Panics
431    /// Panics if `prec` is zero.
432    ///
433    /// # Examples
434    /// ```
435    /// use malachite_float::Float;
436    ///
437    /// let mut x = Float::from(9);
438    /// x.log_base_10_1_plus_x_prec_assign(10);
439    /// assert_eq!(x.to_string(), "1.0000"); // log_10(10) = 1
440    ///
441    /// let mut x = Float::from(99);
442    /// x.log_base_10_1_plus_x_prec_assign(10);
443    /// assert_eq!(x.to_string(), "2.0000"); // log_10(100) = 2
444    /// ```
445    #[inline]
446    pub fn log_base_10_1_plus_x_prec_assign(&mut self, prec: u64) -> Ordering {
447        self.log_base_10_1_plus_x_prec_round_assign(prec, Nearest)
448    }
449
450    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], in place, rounding the result to the
451    /// precision of the input and with the specified rounding mode. An [`Ordering`] is returned,
452    /// indicating whether the rounded value is less than, equal to, or greater than the exact
453    /// value.
454    ///
455    /// See [`Float::log_base_10_1_plus_x_prec_round`] for details and special cases.
456    ///
457    /// # Worst-case complexity
458    /// $T(n) = O(n (\log n)^2 \log\log n)$
459    ///
460    /// $M(n) = O(n \log n)$
461    ///
462    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
463    ///
464    /// # Panics
465    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
466    /// precision.
467    ///
468    /// # Examples
469    /// ```
470    /// use malachite_base::rounding_modes::RoundingMode::*;
471    /// use malachite_float::Float;
472    ///
473    /// let mut x = Float::from(9);
474    /// x.log_base_10_1_plus_x_round_assign(Exact);
475    /// assert_eq!(x.to_string(), "1.00"); // log_10(10) = 1
476    ///
477    /// let mut x = Float::from(99);
478    /// x.log_base_10_1_plus_x_round_assign(Exact);
479    /// assert_eq!(x.to_string(), "2.000"); // log_10(100) = 2
480    /// ```
481    #[inline]
482    pub fn log_base_10_1_plus_x_round_assign(&mut self, rm: RoundingMode) -> Ordering {
483        let prec = self.significant_bits();
484        self.log_base_10_1_plus_x_prec_round_assign(prec, rm)
485    }
486}
487
488impl LogBase10Of1PlusX for Float {
489    type Output = Self;
490
491    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest
492    /// value of the input's precision. The [`Float`] is taken by value.
493    ///
494    /// $\log_{10}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned. See
495    /// [`Float::log_base_10_1_plus_x_prec_round`] for the other special cases.
496    ///
497    /// # Worst-case complexity
498    /// $T(n) = O(n (\log n)^2 \log\log n)$
499    ///
500    /// $M(n) = O(n \log n)$
501    ///
502    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
503    ///
504    /// # Examples
505    /// ```
506    /// use malachite_base::num::arithmetic::traits::LogBase10Of1PlusX;
507    /// use malachite_float::Float;
508    ///
509    /// assert_eq!(Float::from(9).log_base_10_1_plus_x().to_string(), "1.00"); // log_10(10) = 1
510    /// assert_eq!(Float::from(99).log_base_10_1_plus_x().to_string(), "2.000"); // log_10(100) = 2
511    /// ```
512    #[inline]
513    fn log_base_10_1_plus_x(self) -> Self {
514        let prec = self.significant_bits();
515        self.log_base_10_1_plus_x_prec_round(prec, Nearest).0
516    }
517}
518
519impl LogBase10Of1PlusX for &Float {
520    type Output = Float;
521
522    /// Computes $\log_{10}(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest
523    /// value of the input's precision. The [`Float`] is taken by reference.
524    ///
525    /// $\log_{10}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned. See
526    /// [`Float::log_base_10_1_plus_x_prec_round`] for the other special cases.
527    ///
528    /// # Worst-case complexity
529    /// $T(n) = O(n (\log n)^2 \log\log n)$
530    ///
531    /// $M(n) = O(n \log n)$
532    ///
533    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
534    ///
535    /// # Examples
536    /// ```
537    /// use malachite_base::num::arithmetic::traits::LogBase10Of1PlusX;
538    /// use malachite_float::Float;
539    ///
540    /// assert_eq!((&Float::from(9)).log_base_10_1_plus_x().to_string(), "1.00"); // log_10(10) = 1
541    /// assert_eq!(
542    ///     (&Float::from(99)).log_base_10_1_plus_x().to_string(),
543    ///     "2.000"
544    /// ); // log_10(100) = 2
545    /// ```
546    #[inline]
547    fn log_base_10_1_plus_x(self) -> Float {
548        self.log_base_10_1_plus_x_prec_round_ref(self.significant_bits(), Nearest)
549            .0
550    }
551}
552
553impl LogBase10Of1PlusXAssign for Float {
554    /// Replaces a [`Float`] $x$ with $\log_{10}(1+x)$, rounding the result to the nearest value of
555    /// the input's precision.
556    ///
557    /// $\log_{10}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned. See
558    /// [`Float::log_base_10_1_plus_x_prec_round`] for the other special cases.
559    ///
560    /// # Worst-case complexity
561    /// $T(n) = O(n (\log n)^2 \log\log n)$
562    ///
563    /// $M(n) = O(n \log n)$
564    ///
565    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
566    ///
567    /// # Examples
568    /// ```
569    /// use malachite_base::num::arithmetic::traits::LogBase10Of1PlusXAssign;
570    /// use malachite_float::Float;
571    ///
572    /// let mut x = Float::from(9);
573    /// x.log_base_10_1_plus_x_assign();
574    /// assert_eq!(x.to_string(), "1.00"); // log_10(10) = 1
575    ///
576    /// let mut x = Float::from(99);
577    /// x.log_base_10_1_plus_x_assign();
578    /// assert_eq!(x.to_string(), "2.000"); // log_10(100) = 2
579    /// ```
580    #[inline]
581    fn log_base_10_1_plus_x_assign(&mut self) {
582        let prec = self.significant_bits();
583        self.log_base_10_1_plus_x_prec_round_assign(prec, Nearest);
584    }
585}
586
587/// Computes $\log_{10}(1+x)$, the base-10 logarithm of one plus a primitive float. Using this
588/// function is more accurate than computing `(1 + x).log10()`, both because $1+x$ may not be
589/// representable as a primitive float and because the standard library's `log10` is not always
590/// correctly rounded.
591///
592/// $\log_{10}(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
593///
594/// $$
595/// f(x) = \log_{10}(1+x)+\varepsilon.
596/// $$
597/// - If $\log_{10}(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
598///   0.
599/// - If $\log_{10}(1+x)$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
600///   |\log_{10}(1+x)|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a
601///   [`f32`] and 53 if `T` is a [`f64`], but less if the output is subnormal).
602///
603/// Special cases:
604/// - $f(\text{NaN})=\text{NaN}$
605/// - $f(\infty)=\infty$
606/// - $f(-\infty)=\text{NaN}$
607/// - $f(\pm0.0)=\pm0.0$
608/// - $f(-1.0)=-\infty$
609/// - $f(x)=\text{NaN}$ for $x<-1$
610///
611/// This function can underflow (to a subnormal or zero) when $x$ is close to zero, but it cannot
612/// overflow.
613///
614/// # Worst-case complexity
615/// Constant time and additional memory.
616///
617/// # Examples
618/// ```
619/// use malachite_base::num::basic::traits::NegativeInfinity;
620/// use malachite_base::num::float::NiceFloat;
621/// use malachite_float::float::arithmetic::log_base_10_1_plus_x::*;
622///
623/// assert!(primitive_float_log_base_10_1_plus_x(f32::NAN).is_nan());
624/// assert_eq!(
625///     NiceFloat(primitive_float_log_base_10_1_plus_x(f32::INFINITY)),
626///     NiceFloat(f32::INFINITY)
627/// );
628/// assert_eq!(
629///     NiceFloat(primitive_float_log_base_10_1_plus_x(-1.0f32)),
630///     NiceFloat(f32::NEGATIVE_INFINITY)
631/// );
632/// assert!(primitive_float_log_base_10_1_plus_x(-2.0f32).is_nan());
633/// // log_10(1 + 999) = log_10(1000) = 3
634/// assert_eq!(
635///     NiceFloat(primitive_float_log_base_10_1_plus_x(999.0f32)),
636///     NiceFloat(3.0)
637/// );
638/// // log_10(1 + 9) = log_10(10) = 1
639/// assert_eq!(
640///     NiceFloat(primitive_float_log_base_10_1_plus_x(9.0f32)),
641///     NiceFloat(1.0)
642/// );
643/// // log_10(1 + 1) = log_10(2)
644/// assert_eq!(
645///     NiceFloat(primitive_float_log_base_10_1_plus_x(1.0f32)),
646///     NiceFloat(std::f32::consts::LOG10_2)
647/// );
648/// ```
649#[inline]
650#[allow(clippy::type_repetition_in_bounds)]
651pub fn primitive_float_log_base_10_1_plus_x<T: PrimitiveFloat>(x: T) -> T
652where
653    Float: From<T> + PartialOrd<T>,
654    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
655{
656    emulate_float_to_float_fn(Float::log_base_10_1_plus_x_prec, x)
657}