Skip to main content

malachite_float/float/arithmetic/
log_base_10.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::float::arithmetic::ln::{SliverOfOne, sliver_of_one};
17use crate::float::arithmetic::log_base_2::extended_log_base_2_of_rational;
18use crate::float::basic::extended::ExtendedFloat;
19use crate::{
20    Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, float_either_zero,
21    float_infinity, float_nan, float_negative_infinity,
22};
23use core::cmp::Ordering::{self, *};
24use malachite_base::num::arithmetic::traits::{
25    CeilingLogBase2, CheckedLogBase, LogBase10, LogBase10Assign, Sign,
26};
27use malachite_base::num::basic::floats::PrimitiveFloat;
28use malachite_base::num::basic::integers::PrimitiveInt;
29use malachite_base::num::basic::traits::Zero as ZeroTrait;
30use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
31use malachite_base::num::logic::traits::SignificantBits;
32use malachite_base::rounding_modes::RoundingMode::{self, *};
33use malachite_nz::natural::Natural;
34use malachite_nz::natural::arithmetic::float::round::float_can_round;
35use malachite_nz::platform::Limb;
36use malachite_q::Rational;
37
38// Returns `Some(n)` when `x == 10^n` for some integer `n >= 1`. The input `x` must be finite,
39// positive, and not equal to 1.
40//
41// `log_base_10(10^n) = n` is an exactly-representable integer, but the Ziv loop in
42// `log_base_10_prec_round_normal` could never certify it (the computed quotient lands on a
43// representable value the rounding test cannot resolve), so the exact case must be detected up
44// front. This is the `10^n` exactness check from mpfr_log10. Unlike a general base, `10 = 2 * 5` is
45// not a perfect power, so `log_base_10(x)` is rational only when `x` is a power of 10, and then the
46// result is the integer `n` -- there are no dyadic results to handle.
47//
48// The check is balloon-safe. An exact `10^n` has bit length about `n * log2(10)`, but its odd part
49// (the only part stored in the significand) is `5^n`, needing `n * log2(5)` bits, so the bit length
50// is at most about `64 * prec`. When `x`'s exponent exceeds that bound, `x` is too large to be an
51// exact power of 10 and is left to the Ziv loop (which then converges, `x` not being a power of
52// 10), so `x` is materialized as an integer only when doing so is cheap.
53pub(crate) fn float_is_power_of_10(x: &Float) -> Option<u64> {
54    let e = i64::from(x.get_exponent().unwrap());
55    // x < 1 cannot equal 10^n for n >= 1, and only positive exponents can.
56    if e < 1 || u64::exact_from(e) > x.get_prec().unwrap().saturating_mul(64) {
57        return None;
58    }
59    // `Natural::try_from` fails unless `x` is a nonnegative integer.
60    let n = Natural::try_from(x).ok()?;
61    (&n).checked_log_base(&const { Natural::const_from(10) })
62}
63
64// The computation of log_base_10(x) is done by log_base_10(x) = ln(x) / ln(10).
65//
66// This is mpfr_log10 from log10.c, MPFR 4.3.0. The input is finite, nonzero, and positive.
67fn log_base_10_prec_round_normal(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
68    // If x is 1, the result is 0.
69    if *x == 1u32 {
70        return (Float::ZERO, Equal);
71    }
72    // If x = 10^n for some n >= 1, log_base_10(x) = n is exact (though possibly subject to rounding
73    // at the target precision).
74    if let Some(n) = float_is_power_of_10(x) {
75        return Float::from_unsigned_prec_round(n, prec, rm);
76    }
77    // log_10(x) for x in a sliver of 1 can fall below the smallest positive Float; the 1-plus-x
78    // form handles that underflow region.
79    match sliver_of_one(x) {
80        SliverOfOne::Representable(d) => return d.log_base_10_1_plus_x_prec_round(prec, rm),
81        SliverOfOne::Underflow => {
82            return Float::log_base_10_rational_prec_round(Rational::exact_from(x), prec, rm);
83        }
84        SliverOfOne::No => {}
85    }
86    // The result is irrational, so it is never exactly representable.
87    assert_ne!(rm, Exact, "Inexact log_base_10");
88    const TEN: Float = Float::const_from_unsigned(10);
89    // Compute the precision of the intermediary variable: the optimal number of bits, see
90    // algorithms.tex.
91    let mut working_prec = prec + 4 + prec.ceiling_log_base_2();
92    let mut increment = Limb::WIDTH;
93    loop {
94        // ln(x) / ln(10). ln(x), ln(10), and the division are each correctly rounded (at most 1/2
95        // ulp), so the relative error is below 2^(2 - working_prec) and working_prec - 4 correct
96        // bits suffice for rounding (mpfr_log10 uses Nt - 4).
97        let t = x
98            .ln_prec_ref(working_prec)
99            .0
100            .div_prec(TEN.ln_prec(working_prec).0, working_prec)
101            .0;
102        if float_can_round(t.significand_ref().unwrap(), working_prec - 4, prec, rm) {
103            return Float::from_float_prec_round(t, prec, rm);
104        }
105        // Increase the precision.
106        working_prec += increment;
107        increment = working_prec >> 1;
108    }
109}
110
111// Computes log_base_10(x) for a positive `Rational` x whose logarithm is irrational, in a Ziv loop.
112//
113// log_base_10(x) = log_2(x) / log_2(10). As in log_base_rational, routing through
114// `log_base_2_rational` (rather than computing `ln(x) / ln(10)` directly) reuses its handling of x
115// near a power of 2 -- in particular x near 1, where the result is near 0 and a direct computation
116// would need a working precision proportional to how close x is to 1. log_2(x), log_2(10), and the
117// division are each correctly rounded (at most 1/2 ulp), so the relative error is below 2^(2 -
118// working_prec) and working_prec - 4 correct bits suffice for rounding.
119fn log_base_10_rational_prec_round_helper(
120    x: &Rational,
121    prec: u64,
122    rm: RoundingMode,
123) -> (Float, Ordering) {
124    const TEN: Float = Float::const_from_unsigned(10);
125    // The initial slack keeps working_prec at least 7, so the working_prec - 6 below stays
126    // positive.
127    let mut working_prec = prec + 6 + prec.ceiling_log_base_2();
128    let mut increment = Limb::WIDTH;
129    loop {
130        // log_2(x) in the extended exponent range: for x within a sliver of 1 the ordinary Float
131        // form would flush to zero or clamp, and the rounding test below could never resolve it.
132        let num = extended_log_base_2_of_rational(x, working_prec);
133        let den = ExtendedFloat::from(TEN.log_base_2_prec(working_prec).0);
134        let quotient = num.div_prec_val_ref(&den, working_prec).0;
135        // log_2(x) is within 2 ulps, log_2(10) within 1/2, and the division adds 1/2 more, so
136        // working_prec - 6 correct bits comfortably suffice.
137        if float_can_round(
138            quotient.x.significand_ref().unwrap(),
139            working_prec - 6,
140            prec,
141            rm,
142        ) {
143            let (rounded, o) = Float::from_float_prec_round(quotient.x, prec, rm);
144            let mut result = ExtendedFloat::from(rounded);
145            result.exp = result.exp.checked_add(quotient.exp).unwrap();
146            return result.into_float_helper(prec, rm, o);
147        }
148        // Increase the precision.
149        working_prec += increment;
150        increment = working_prec >> 1;
151    }
152}
153
154impl Float {
155    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the specified
156    /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
157    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
158    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
159    /// whenever this function returns a `NaN` it also returns `Equal`.
160    ///
161    /// The base-10 logarithm of any nonzero negative number is `NaN`.
162    ///
163    /// See [`RoundingMode`] for a description of the possible rounding modes.
164    ///
165    /// $$
166    /// f(x,p,m) = \log_{10} x+\varepsilon.
167    /// $$
168    /// - If $\log_{10} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
169    ///   be 0.
170    /// - If $\log_{10} x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
171    ///   2^{\lfloor\log_2 |\log_{10} x|\rfloor-p+1}$.
172    /// - If $\log_{10} x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
173    ///   2^{\lfloor\log_2 |\log_{10} x|\rfloor-p}$.
174    ///
175    /// If the output has a precision, it is `prec`.
176    ///
177    /// Special cases:
178    /// - $f(\text{NaN},p,m)=\text{NaN}$
179    /// - $f(\infty,p,m)=\infty$
180    /// - $f(-\infty,p,m)=\text{NaN}$
181    /// - $f(\pm0.0,p,m)=-\infty$
182    /// - $f(1.0,p,m)=0.0$, and the result is exact
183    /// - $f(10^n,p,m)=n$, rounded to precision $p$; the result is exact if and only if $n$ is
184    ///   representable with precision $p$
185    /// - $f(x,p,m)=\text{NaN}$ for $x<0$
186    ///
187    /// If you know you'll be using `Nearest`, consider using [`Float::log_base_10_prec`] instead.
188    /// If you know that your target precision is the precision of the input, consider using
189    /// [`Float::log_base_10_round`] instead. If both of these things are true, consider using
190    /// [`Float::log_base_10`] instead.
191    ///
192    /// # Worst-case complexity
193    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
194    ///
195    /// $M(n, m) = O(n \log n + m \log m)$
196    ///
197    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
198    /// `self.significant_bits()`.
199    ///
200    /// # Panics
201    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
202    /// with the given precision.
203    ///
204    /// # Examples
205    /// ```
206    /// use malachite_base::rounding_modes::RoundingMode::*;
207    /// use malachite_float::Float;
208    /// use std::cmp::Ordering::*;
209    ///
210    /// let (log, o) = Float::from(1000).log_base_10_prec_round(10, Nearest);
211    /// assert_eq!(log.to_string(), "3.0000");
212    /// assert_eq!(o, Equal);
213    ///
214    /// let (log, o) = Float::from(50).log_base_10_prec_round(10, Floor);
215    /// assert_eq!(log.to_string(), "1.6973");
216    /// assert_eq!(o, Less);
217    ///
218    /// let (log, o) = Float::from(50).log_base_10_prec_round(10, Ceiling);
219    /// assert_eq!(log.to_string(), "1.6992");
220    /// assert_eq!(o, Greater);
221    /// ```
222    #[inline]
223    pub fn log_base_10_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
224        assert_ne!(prec, 0);
225        match self {
226            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
227                (float_nan!(), Equal)
228            }
229            float_either_zero!() => (float_negative_infinity!(), Equal),
230            float_infinity!() => (float_infinity!(), Equal),
231            _ => log_base_10_prec_round_normal(&self, prec, rm),
232        }
233    }
234
235    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the specified
236    /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
237    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
238    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
239    /// whenever this function returns a `NaN` it also returns `Equal`.
240    ///
241    /// See [`Float::log_base_10_prec_round`] for details, special cases, and a description of the
242    /// rounding behavior.
243    ///
244    /// # Worst-case complexity
245    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
246    ///
247    /// $M(n, m) = O(n \log n + m \log m)$
248    ///
249    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
250    /// `self.significant_bits()`.
251    ///
252    /// # Panics
253    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
254    /// with the given precision.
255    ///
256    /// # Examples
257    /// ```
258    /// use malachite_base::rounding_modes::RoundingMode::*;
259    /// use malachite_float::Float;
260    /// use std::cmp::Ordering::*;
261    ///
262    /// let (log, o) = Float::from(1000).log_base_10_prec_round_ref(10, Nearest);
263    /// assert_eq!(log.to_string(), "3.0000");
264    /// assert_eq!(o, Equal);
265    /// ```
266    #[inline]
267    pub fn log_base_10_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
268        assert_ne!(prec, 0);
269        match self {
270            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
271                (float_nan!(), Equal)
272            }
273            float_either_zero!() => (float_negative_infinity!(), Equal),
274            float_infinity!() => (float_infinity!(), Equal),
275            _ => log_base_10_prec_round_normal(self, prec, rm),
276        }
277    }
278
279    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
280    /// of the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also
281    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
282    /// exact value.
283    ///
284    /// See [`Float::log_base_10_prec_round`] for details and special cases.
285    ///
286    /// # Worst-case complexity
287    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
288    ///
289    /// $M(n, m) = O(n \log n + m \log m)$
290    ///
291    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
292    /// `self.significant_bits()`.
293    ///
294    /// # Panics
295    /// Panics if `prec` is zero.
296    ///
297    /// # Examples
298    /// ```
299    /// use malachite_float::Float;
300    /// use std::cmp::Ordering::*;
301    ///
302    /// let (log, o) = Float::from(50).log_base_10_prec(10);
303    /// assert_eq!(log.to_string(), "1.6992");
304    /// assert_eq!(o, Greater);
305    /// ```
306    #[inline]
307    pub fn log_base_10_prec(self, prec: u64) -> (Self, Ordering) {
308        self.log_base_10_prec_round(prec, Nearest)
309    }
310
311    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
312    /// of the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
313    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
314    /// exact value.
315    ///
316    /// See [`Float::log_base_10_prec_round`] for details and special cases.
317    ///
318    /// # Worst-case complexity
319    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
320    ///
321    /// $M(n, m) = O(n \log n + m \log m)$
322    ///
323    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
324    /// `self.significant_bits()`.
325    ///
326    /// # Panics
327    /// Panics if `prec` is zero.
328    ///
329    /// # Examples
330    /// ```
331    /// use malachite_float::Float;
332    /// use std::cmp::Ordering::*;
333    ///
334    /// let (log, o) = Float::from(50).log_base_10_prec_ref(10);
335    /// assert_eq!(log.to_string(), "1.6992");
336    /// assert_eq!(o, Greater);
337    /// ```
338    #[inline]
339    pub fn log_base_10_prec_ref(&self, prec: u64) -> (Self, Ordering) {
340        self.log_base_10_prec_round_ref(prec, Nearest)
341    }
342
343    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the precision of
344    /// the input and with the specified rounding mode. The [`Float`] is taken by value. An
345    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
346    /// or greater than the exact value.
347    ///
348    /// See [`Float::log_base_10_prec_round`] for details and special cases.
349    ///
350    /// # Worst-case complexity
351    /// $T(n) = O(n (\log n)^2 \log\log n)$
352    ///
353    /// $M(n) = O(n \log n)$
354    ///
355    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
356    ///
357    /// # Panics
358    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
359    /// precision.
360    ///
361    /// # Examples
362    /// ```
363    /// use malachite_base::rounding_modes::RoundingMode::*;
364    /// use malachite_float::Float;
365    /// use std::cmp::Ordering::*;
366    ///
367    /// let (log, o) = Float::from(1000).log_base_10_round(Floor);
368    /// assert_eq!(log.to_string(), "3.000");
369    /// assert_eq!(o, Equal);
370    /// ```
371    #[inline]
372    pub fn log_base_10_round(self, rm: RoundingMode) -> (Self, Ordering) {
373        let prec = self.significant_bits();
374        self.log_base_10_prec_round(prec, rm)
375    }
376
377    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the precision of
378    /// the input and with the specified rounding mode. The [`Float`] is taken by reference. An
379    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
380    /// or greater than the exact value.
381    ///
382    /// See [`Float::log_base_10_prec_round`] for details and special cases.
383    ///
384    /// # Worst-case complexity
385    /// $T(n) = O(n (\log n)^2 \log\log n)$
386    ///
387    /// $M(n) = O(n \log n)$
388    ///
389    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
390    ///
391    /// # Panics
392    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
393    /// precision.
394    ///
395    /// # Examples
396    /// ```
397    /// use malachite_base::rounding_modes::RoundingMode::*;
398    /// use malachite_float::Float;
399    /// use std::cmp::Ordering::*;
400    ///
401    /// let (log, o) = Float::from(100).log_base_10_round_ref(Ceiling);
402    /// assert_eq!(log.to_string(), "2.00");
403    /// assert_eq!(o, Equal);
404    /// ```
405    #[inline]
406    pub fn log_base_10_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
407        self.log_base_10_prec_round_ref(self.significant_bits(), rm)
408    }
409
410    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
411    /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
412    /// indicating whether the rounded value is less than, equal to, or greater than the exact
413    /// value.
414    ///
415    /// See [`Float::log_base_10_prec_round`] for details and special cases.
416    ///
417    /// # Worst-case complexity
418    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
419    ///
420    /// $M(n, m) = O(n \log n + m \log m)$
421    ///
422    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
423    /// `self.significant_bits()`.
424    ///
425    /// # Panics
426    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
427    /// with the given precision.
428    ///
429    /// # Examples
430    /// ```
431    /// use malachite_base::rounding_modes::RoundingMode::*;
432    /// use malachite_float::Float;
433    /// use std::cmp::Ordering::*;
434    ///
435    /// let mut x = Float::from(50);
436    /// let o = x.log_base_10_prec_round_assign(10, Floor);
437    /// assert_eq!(x.to_string(), "1.6973");
438    /// assert_eq!(o, Less);
439    /// ```
440    #[inline]
441    pub fn log_base_10_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
442        let (result, o) = core::mem::take(self).log_base_10_prec_round(prec, rm);
443        *self = result;
444        o
445    }
446
447    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
448    /// nearest value of the specified precision. An [`Ordering`] is returned, indicating whether
449    /// the rounded value is less than, equal to, or greater than the exact value.
450    ///
451    /// See [`Float::log_base_10_prec_round`] for details and special cases.
452    ///
453    /// # Worst-case complexity
454    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
455    ///
456    /// $M(n, m) = O(n \log n + m \log m)$
457    ///
458    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
459    /// `self.significant_bits()`.
460    ///
461    /// # Panics
462    /// Panics if `prec` is zero.
463    ///
464    /// # Examples
465    /// ```
466    /// use malachite_float::Float;
467    /// use std::cmp::Ordering::*;
468    ///
469    /// let mut x = Float::from(1000);
470    /// let o = x.log_base_10_prec_assign(10);
471    /// assert_eq!(x.to_string(), "3.0000");
472    /// assert_eq!(o, Equal);
473    /// ```
474    #[inline]
475    pub fn log_base_10_prec_assign(&mut self, prec: u64) -> Ordering {
476        self.log_base_10_prec_round_assign(prec, Nearest)
477    }
478
479    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
480    /// precision of the input and with the specified rounding mode. An [`Ordering`] is returned,
481    /// indicating whether the rounded value is less than, equal to, or greater than the exact
482    /// value.
483    ///
484    /// See [`Float::log_base_10_prec_round`] for details and special cases.
485    ///
486    /// # Worst-case complexity
487    /// $T(n) = O(n (\log n)^2 \log\log n)$
488    ///
489    /// $M(n) = O(n \log n)$
490    ///
491    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
492    ///
493    /// # Panics
494    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
495    /// precision.
496    ///
497    /// # Examples
498    /// ```
499    /// use malachite_base::rounding_modes::RoundingMode::*;
500    /// use malachite_float::Float;
501    /// use std::cmp::Ordering::*;
502    ///
503    /// let mut x = Float::from(100);
504    /// let o = x.log_base_10_round_assign(Nearest);
505    /// assert_eq!(x.to_string(), "2.00");
506    /// assert_eq!(o, Equal);
507    /// ```
508    #[inline]
509    pub fn log_base_10_round_assign(&mut self, rm: RoundingMode) -> Ordering {
510        let prec = self.significant_bits();
511        self.log_base_10_prec_round_assign(prec, rm)
512    }
513
514    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the specified
515    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
516    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
517    /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
518    /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
519    /// `Equal`.
520    ///
521    /// The base-10 logarithm of any negative number is `NaN`.
522    ///
523    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
524    /// or too small to be representable as [`Float`]s. Neither overflow nor underflow of the output
525    /// is possible.
526    ///
527    /// See [`Float::log_base_10_prec_round`] for details and a description of the rounding
528    /// behavior.
529    ///
530    /// Special cases:
531    /// - $f(0,p,m)=-\infty$
532    /// - $f(x,p,m)=\text{NaN}$ for $x<0$
533    /// - $f(1,p,m)=0.0$, and the result is exact
534    /// - $f(10^n,p,m)=n$, rounded to precision $p$; the result is exact if and only if the integer
535    ///   $n$ is representable with precision $p$. This includes negative powers of 10 like $1/100$,
536    ///   and powers of 10 whose exponents lie far outside the exponent range of [`Float`].
537    ///
538    /// # Worst-case complexity
539    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
540    ///
541    /// $M(n, m) = O(n \log n + m \log m)$
542    ///
543    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
544    /// `x.significant_bits()`.
545    ///
546    /// # Panics
547    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
548    /// with the given precision. (The result is exactly representable if and only if $x \leq 0$ or
549    /// $x$ is a power of 10 whose base-10 logarithm is representable with the given precision.)
550    ///
551    /// # Examples
552    /// ```
553    /// use malachite_base::rounding_modes::RoundingMode::*;
554    /// use malachite_float::Float;
555    /// use malachite_q::Rational;
556    /// use std::cmp::Ordering::*;
557    ///
558    /// let (log, o) = Float::log_base_10_rational_prec_round(Rational::from(1000), 10, Exact);
559    /// assert_eq!(log.to_string(), "3.0000");
560    /// assert_eq!(o, Equal);
561    ///
562    /// let (log, o) =
563    ///     Float::log_base_10_rational_prec_round(Rational::from_signeds(1, 100), 10, Exact);
564    /// assert_eq!(log.to_string(), "-2.0000"); // log_10(1/100) = -2
565    /// assert_eq!(o, Equal);
566    /// ```
567    #[allow(clippy::needless_pass_by_value)]
568    #[inline]
569    pub fn log_base_10_rational_prec_round(
570        x: Rational,
571        prec: u64,
572        rm: RoundingMode,
573    ) -> (Self, Ordering) {
574        Self::log_base_10_rational_prec_round_ref(&x, prec, rm)
575    }
576
577    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the specified
578    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
579    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
580    /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
581    /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
582    /// `Equal`.
583    ///
584    /// See [`Float::log_base_10_rational_prec_round`] for details, special cases, and a description
585    /// of the rounding behavior.
586    ///
587    /// # Worst-case complexity
588    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
589    ///
590    /// $M(n, m) = O(n \log n + m \log m)$
591    ///
592    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
593    /// `x.significant_bits()`.
594    ///
595    /// # Panics
596    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
597    /// with the given precision.
598    ///
599    /// # Examples
600    /// ```
601    /// use malachite_base::rounding_modes::RoundingMode::*;
602    /// use malachite_float::Float;
603    /// use malachite_q::Rational;
604    /// use std::cmp::Ordering::*;
605    ///
606    /// let (log, o) =
607    ///     Float::log_base_10_rational_prec_round_ref(&Rational::from(1000), 10, Nearest);
608    /// assert_eq!(log.to_string(), "3.0000");
609    /// assert_eq!(o, Equal);
610    /// ```
611    pub fn log_base_10_rational_prec_round_ref(
612        x: &Rational,
613        prec: u64,
614        rm: RoundingMode,
615    ) -> (Self, Ordering) {
616        assert_ne!(prec, 0);
617        match x.sign() {
618            Equal => return (float_negative_infinity!(), Equal),
619            Less => return (float_nan!(), Equal),
620            Greater => {}
621        }
622        // If x = 10^m, then log_base_10(x) = m is an exact integer (m may be negative, for x < 1).
623        // The Ziv loop could never certify it (see float_is_power_of_10 for the Float analog).
624        if let Some(m) = x.checked_log_base(10) {
625            return Self::from_signed_prec_round(m, prec, rm);
626        }
627        // The result is irrational, so it is never exactly representable.
628        assert_ne!(rm, Exact, "Inexact log_base_10");
629        log_base_10_rational_prec_round_helper(x, prec, rm)
630    }
631
632    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the nearest
633    /// value of the specified precision and returning the result as a [`Float`]. The [`Rational`]
634    /// is taken by value. An [`Ordering`] is also returned, indicating whether the rounded value is
635    /// less than, equal to, or greater than the exact value.
636    ///
637    /// See [`Float::log_base_10_rational_prec_round`] for details and special cases.
638    ///
639    /// # Worst-case complexity
640    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
641    ///
642    /// $M(n, m) = O(n \log n + m \log m)$
643    ///
644    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
645    /// `x.significant_bits()`.
646    ///
647    /// # Panics
648    /// Panics if `prec` is zero.
649    ///
650    /// # Examples
651    /// ```
652    /// use malachite_float::Float;
653    /// use malachite_q::Rational;
654    /// use std::cmp::Ordering::*;
655    ///
656    /// let (log, o) = Float::log_base_10_rational_prec(Rational::from_signeds(1, 100), 10);
657    /// assert_eq!(log.to_string(), "-2.0000");
658    /// assert_eq!(o, Equal);
659    /// ```
660    #[inline]
661    pub fn log_base_10_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
662        Self::log_base_10_rational_prec_round(x, prec, Nearest)
663    }
664
665    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the nearest
666    /// value of the specified precision and returning the result as a [`Float`]. The [`Rational`]
667    /// is taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
668    /// value is less than, equal to, or greater than the exact value.
669    ///
670    /// See [`Float::log_base_10_rational_prec_round`] for details and special cases.
671    ///
672    /// # Worst-case complexity
673    /// $T(n, m) = O(n (\log n)^2 \log\log n + m \log m \log\log m)$
674    ///
675    /// $M(n, m) = O(n \log n + m \log m)$
676    ///
677    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
678    /// `x.significant_bits()`.
679    ///
680    /// # Panics
681    /// Panics if `prec` is zero.
682    ///
683    /// # Examples
684    /// ```
685    /// use malachite_float::Float;
686    /// use malachite_q::Rational;
687    /// use std::cmp::Ordering::*;
688    ///
689    /// let (log, o) = Float::log_base_10_rational_prec_ref(&Rational::from(50), 10);
690    /// assert_eq!(log.to_string(), "1.6992");
691    /// assert_eq!(o, Greater);
692    /// ```
693    #[inline]
694    pub fn log_base_10_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
695        Self::log_base_10_rational_prec_round_ref(x, prec, Nearest)
696    }
697}
698
699impl LogBase10 for Float {
700    type Output = Self;
701
702    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
703    /// of the input's precision. The [`Float`] is taken by value.
704    ///
705    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
706    /// [`Float::log_base_10_prec_round`] for the special cases.
707    ///
708    /// $$
709    /// f(x) = \log_{10} x+\varepsilon,
710    /// $$
711    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_{10} x|\rfloor-p}$ and $p$ is the precision
712    /// of the input.
713    ///
714    /// # Worst-case complexity
715    /// $T(n) = O(n (\log n)^2 \log\log n)$
716    ///
717    /// $M(n) = O(n \log n)$
718    ///
719    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
720    ///
721    /// # Examples
722    /// ```
723    /// use malachite_base::num::arithmetic::traits::LogBase10;
724    /// use malachite_float::Float;
725    ///
726    /// assert_eq!(Float::from(1000).log_base_10().to_string(), "3.000");
727    /// assert_eq!(Float::from(100).log_base_10().to_string(), "2.00");
728    /// ```
729    #[inline]
730    fn log_base_10(self) -> Self {
731        let prec = self.significant_bits();
732        self.log_base_10_prec_round(prec, Nearest).0
733    }
734}
735
736impl LogBase10 for &Float {
737    type Output = Float;
738
739    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
740    /// of the input's precision. The [`Float`] is taken by reference.
741    ///
742    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
743    /// [`Float::log_base_10_prec_round`] for the special cases.
744    ///
745    /// $$
746    /// f(x) = \log_{10} x+\varepsilon,
747    /// $$
748    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_{10} x|\rfloor-p}$ and $p$ is the precision
749    /// of the input.
750    ///
751    /// # Worst-case complexity
752    /// $T(n) = O(n (\log n)^2 \log\log n)$
753    ///
754    /// $M(n) = O(n \log n)$
755    ///
756    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
757    ///
758    /// # Examples
759    /// ```
760    /// use malachite_base::num::arithmetic::traits::LogBase10;
761    /// use malachite_float::Float;
762    ///
763    /// assert_eq!((&Float::from(1000)).log_base_10().to_string(), "3.000");
764    /// ```
765    #[inline]
766    fn log_base_10(self) -> Float {
767        self.log_base_10_prec_round_ref(self.significant_bits(), Nearest)
768            .0
769    }
770}
771
772impl LogBase10Assign for Float {
773    /// Replaces a [`Float`] $x$ with $\log_{10} x$, rounding the result to the nearest value of the
774    /// input's precision.
775    ///
776    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
777    /// [`Float::log_base_10_prec_round`] for the special cases.
778    ///
779    /// # Worst-case complexity
780    /// $T(n) = O(n (\log n)^2 \log\log n)$
781    ///
782    /// $M(n) = O(n \log n)$
783    ///
784    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
785    ///
786    /// # Examples
787    /// ```
788    /// use malachite_base::num::arithmetic::traits::LogBase10Assign;
789    /// use malachite_float::Float;
790    ///
791    /// let mut x = Float::from(1000);
792    /// x.log_base_10_assign();
793    /// assert_eq!(x.to_string(), "3.000");
794    /// ```
795    #[inline]
796    fn log_base_10_assign(&mut self) {
797        let prec = self.significant_bits();
798        self.log_base_10_prec_round_assign(prec, Nearest);
799    }
800}
801
802/// Computes $\log_{10} x$, the base-10 logarithm of a primitive float. Using this function is more
803/// accurate than using the primitive float `log10` function (the standard library's `log10` is not
804/// always correctly rounded).
805///
806/// The base-10 logarithm of any negative number is `NaN`.
807///
808/// $$
809/// f(x) = \log_{10} x+\varepsilon.
810/// $$
811/// - If $\log_{10} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
812/// - If $\log_{10} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{10}
813///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
814///   if `T` is a [`f64`], but less if the output is subnormal).
815///
816/// Special cases:
817/// - $f(\text{NaN})=\text{NaN}$
818/// - $f(\infty)=\infty$
819/// - $f(-\infty)=\text{NaN}$
820/// - $f(\pm0.0)=-\infty$
821/// - $f(1.0)=0.0$
822/// - $f(x)=\text{NaN}$ for $x<0$
823///
824/// Neither overflow nor underflow is possible.
825///
826/// # Worst-case complexity
827/// Constant time and additional memory.
828///
829/// # Examples
830/// ```
831/// use malachite_base::num::basic::traits::NegativeInfinity;
832/// use malachite_base::num::float::NiceFloat;
833/// use malachite_float::float::arithmetic::log_base_10::primitive_float_log_base_10;
834///
835/// assert!(primitive_float_log_base_10(f32::NAN).is_nan());
836/// assert_eq!(
837///     NiceFloat(primitive_float_log_base_10(f32::INFINITY)),
838///     NiceFloat(f32::INFINITY)
839/// );
840/// assert_eq!(
841///     NiceFloat(primitive_float_log_base_10(0.0f32)),
842///     NiceFloat(f32::NEGATIVE_INFINITY)
843/// );
844/// // log_10(1000) = 3
845/// assert_eq!(
846///     NiceFloat(primitive_float_log_base_10(1000.0f32)),
847///     NiceFloat(3.0)
848/// );
849/// // log_10(50)
850/// assert_eq!(
851///     NiceFloat(primitive_float_log_base_10(50.0f32)),
852///     NiceFloat(1.69897)
853/// );
854/// assert!(primitive_float_log_base_10(-1.0f32).is_nan());
855/// ```
856#[inline]
857#[allow(clippy::type_repetition_in_bounds)]
858pub fn primitive_float_log_base_10<T: PrimitiveFloat>(x: T) -> T
859where
860    Float: From<T> + PartialOrd<T>,
861    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
862{
863    emulate_float_to_float_fn(Float::log_base_10_prec, x)
864}
865
866/// Computes $\log_{10} x$, the base-10 logarithm of a [`Rational`], returning a primitive float
867/// result.
868///
869/// If the logarithm is equidistant from two primitive floats, the primitive float with fewer 1s in
870/// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
871/// mode.
872///
873/// The base-10 logarithm of any negative number is `NaN`.
874///
875/// $$
876/// f(x) = \log_{10} x+\varepsilon.
877/// $$
878/// - If $\log_{10} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
879/// - If $\log_{10} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{10}
880///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
881///   if `T` is a [`f64`], but less if the output is subnormal).
882///
883/// Special cases:
884/// - $f(0)=-\infty$
885/// - $f(x)=\text{NaN}$ for $x<0$
886/// - $f(1)=0.0$
887///
888/// Neither overflow nor underflow is possible.
889///
890/// # Worst-case complexity
891/// $T(m) = O(m \log m \log\log m)$
892///
893/// $M(m) = O(m \log m)$
894///
895/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
896///
897/// # Examples
898/// ```
899/// use malachite_base::num::basic::traits::{NegativeInfinity, Zero};
900/// use malachite_base::num::float::NiceFloat;
901/// use malachite_float::float::arithmetic::log_base_10::primitive_float_log_base_10_rational;
902/// use malachite_q::Rational;
903///
904/// assert_eq!(
905///     NiceFloat(primitive_float_log_base_10_rational::<f64>(&Rational::ZERO)),
906///     NiceFloat(f64::NEGATIVE_INFINITY)
907/// );
908/// // log_10(1000) = 3
909/// assert_eq!(
910///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
911///         &Rational::from(1000)
912///     )),
913///     NiceFloat(3.0)
914/// );
915/// // log_10(1/3)
916/// assert_eq!(
917///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
918///         &Rational::from_unsigneds(1u8, 3)
919///     )),
920///     NiceFloat(-0.47712125471966244)
921/// );
922/// assert_eq!(
923///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
924///         &Rational::from(-1000)
925///     )),
926///     NiceFloat(f64::NAN)
927/// );
928/// ```
929#[inline]
930#[allow(clippy::type_repetition_in_bounds)]
931pub fn primitive_float_log_base_10_rational<T: PrimitiveFloat>(x: &Rational) -> T
932where
933    Float: PartialOrd<T>,
934    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
935{
936    emulate_rational_to_float_fn(Float::log_base_10_rational_prec_ref, x)
937}