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_extras::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) = O(n (\log n)^2 \log\log n)$
194    ///
195    /// $M(n) = O(n (\log n)^2)$
196    ///
197    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
198    ///
199    /// # Panics
200    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
201    /// with the given precision.
202    ///
203    /// # Examples
204    /// ```
205    /// use malachite_base::rounding_modes::RoundingMode::*;
206    /// use malachite_float::Float;
207    /// use std::cmp::Ordering::*;
208    ///
209    /// let (log, o) = Float::from(1000).log_base_10_prec_round(10, Nearest);
210    /// assert_eq!(log.to_string(), "3.0000");
211    /// assert_eq!(o, Equal);
212    ///
213    /// let (log, o) = Float::from(50).log_base_10_prec_round(10, Floor);
214    /// assert_eq!(log.to_string(), "1.6973");
215    /// assert_eq!(o, Less);
216    ///
217    /// let (log, o) = Float::from(50).log_base_10_prec_round(10, Ceiling);
218    /// assert_eq!(log.to_string(), "1.6992");
219    /// assert_eq!(o, Greater);
220    /// ```
221    #[inline]
222    pub fn log_base_10_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
223        assert_ne!(prec, 0);
224        match self {
225            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
226                (float_nan!(), Equal)
227            }
228            float_either_zero!() => (float_negative_infinity!(), Equal),
229            float_infinity!() => (float_infinity!(), Equal),
230            _ => log_base_10_prec_round_normal(&self, prec, rm),
231        }
232    }
233
234    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the specified
235    /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
236    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
237    /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
238    /// whenever this function returns a `NaN` it also returns `Equal`.
239    ///
240    /// See [`Float::log_base_10_prec_round`] for details, special cases, and a description of the
241    /// rounding behavior.
242    ///
243    /// # Worst-case complexity
244    /// $T(n) = O(n (\log n)^2 \log\log n)$
245    ///
246    /// $M(n) = O(n (\log n)^2)$
247    ///
248    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
249    ///
250    /// # Panics
251    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
252    /// with the given precision.
253    ///
254    /// # Examples
255    /// ```
256    /// use malachite_base::rounding_modes::RoundingMode::*;
257    /// use malachite_float::Float;
258    /// use std::cmp::Ordering::*;
259    ///
260    /// let (log, o) = Float::from(1000).log_base_10_prec_round_ref(10, Nearest);
261    /// assert_eq!(log.to_string(), "3.0000");
262    /// assert_eq!(o, Equal);
263    /// ```
264    #[inline]
265    pub fn log_base_10_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
266        assert_ne!(prec, 0);
267        match self {
268            Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
269                (float_nan!(), Equal)
270            }
271            float_either_zero!() => (float_negative_infinity!(), Equal),
272            float_infinity!() => (float_infinity!(), Equal),
273            _ => log_base_10_prec_round_normal(self, prec, rm),
274        }
275    }
276
277    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
278    /// of the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also
279    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
280    /// exact value.
281    ///
282    /// See [`Float::log_base_10_prec_round`] for details and special cases.
283    ///
284    /// # Worst-case complexity
285    /// $T(n) = O(n (\log n)^2 \log\log n)$
286    ///
287    /// $M(n) = O(n (\log n)^2)$
288    ///
289    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
290    ///
291    /// # Panics
292    /// Panics if `prec` is zero.
293    ///
294    /// # Examples
295    /// ```
296    /// use malachite_float::Float;
297    /// use std::cmp::Ordering::*;
298    ///
299    /// let (log, o) = Float::from(50).log_base_10_prec(10);
300    /// assert_eq!(log.to_string(), "1.6992");
301    /// assert_eq!(o, Greater);
302    /// ```
303    #[inline]
304    pub fn log_base_10_prec(self, prec: u64) -> (Self, Ordering) {
305        self.log_base_10_prec_round(prec, Nearest)
306    }
307
308    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
309    /// of the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
310    /// returned, indicating whether the rounded value is less than, equal to, or greater than the
311    /// exact value.
312    ///
313    /// See [`Float::log_base_10_prec_round`] for details and special cases.
314    ///
315    /// # Worst-case complexity
316    /// $T(n) = O(n (\log n)^2 \log\log n)$
317    ///
318    /// $M(n) = O(n (\log n)^2)$
319    ///
320    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
321    ///
322    /// # Panics
323    /// Panics if `prec` is zero.
324    ///
325    /// # Examples
326    /// ```
327    /// use malachite_float::Float;
328    /// use std::cmp::Ordering::*;
329    ///
330    /// let (log, o) = Float::from(50).log_base_10_prec_ref(10);
331    /// assert_eq!(log.to_string(), "1.6992");
332    /// assert_eq!(o, Greater);
333    /// ```
334    #[inline]
335    pub fn log_base_10_prec_ref(&self, prec: u64) -> (Self, Ordering) {
336        self.log_base_10_prec_round_ref(prec, Nearest)
337    }
338
339    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the precision of
340    /// the input and with the specified rounding mode. The [`Float`] is taken by value. An
341    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
342    /// or greater than the exact value.
343    ///
344    /// See [`Float::log_base_10_prec_round`] for details and special cases.
345    ///
346    /// # Worst-case complexity
347    /// $T(n) = O(n (\log n)^2 \log\log n)$
348    ///
349    /// $M(n) = O(n (\log n)^2)$
350    ///
351    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
352    ///
353    /// # Panics
354    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
355    /// precision.
356    ///
357    /// # Examples
358    /// ```
359    /// use malachite_base::rounding_modes::RoundingMode::*;
360    /// use malachite_float::Float;
361    /// use std::cmp::Ordering::*;
362    ///
363    /// let (log, o) = Float::from(1000).log_base_10_round(Floor);
364    /// assert_eq!(log.to_string(), "3.000");
365    /// assert_eq!(o, Equal);
366    /// ```
367    #[inline]
368    pub fn log_base_10_round(self, rm: RoundingMode) -> (Self, Ordering) {
369        let prec = self.significant_bits();
370        self.log_base_10_prec_round(prec, rm)
371    }
372
373    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the precision of
374    /// the input and with the specified rounding mode. The [`Float`] is taken by reference. An
375    /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
376    /// or greater than the exact value.
377    ///
378    /// See [`Float::log_base_10_prec_round`] for details and special cases.
379    ///
380    /// # Worst-case complexity
381    /// $T(n) = O(n (\log n)^2 \log\log n)$
382    ///
383    /// $M(n) = O(n (\log n)^2)$
384    ///
385    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
386    ///
387    /// # Panics
388    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
389    /// precision.
390    ///
391    /// # Examples
392    /// ```
393    /// use malachite_base::rounding_modes::RoundingMode::*;
394    /// use malachite_float::Float;
395    /// use std::cmp::Ordering::*;
396    ///
397    /// let (log, o) = Float::from(100).log_base_10_round_ref(Ceiling);
398    /// assert_eq!(log.to_string(), "2.00");
399    /// assert_eq!(o, Equal);
400    /// ```
401    #[inline]
402    pub fn log_base_10_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
403        self.log_base_10_prec_round_ref(self.significant_bits(), rm)
404    }
405
406    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
407    /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
408    /// indicating whether the rounded value is less than, equal to, or greater than the exact
409    /// value.
410    ///
411    /// See [`Float::log_base_10_prec_round`] for details and special cases.
412    ///
413    /// # Worst-case complexity
414    /// $T(n) = O(n (\log n)^2 \log\log n)$
415    ///
416    /// $M(n) = O(n (\log n)^2)$
417    ///
418    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
419    ///
420    /// # Panics
421    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
422    /// with the given precision.
423    ///
424    /// # Examples
425    /// ```
426    /// use malachite_base::rounding_modes::RoundingMode::*;
427    /// use malachite_float::Float;
428    /// use std::cmp::Ordering::*;
429    ///
430    /// let mut x = Float::from(50);
431    /// let o = x.log_base_10_prec_round_assign(10, Floor);
432    /// assert_eq!(x.to_string(), "1.6973");
433    /// assert_eq!(o, Less);
434    /// ```
435    #[inline]
436    pub fn log_base_10_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
437        let (result, o) = core::mem::take(self).log_base_10_prec_round(prec, rm);
438        *self = result;
439        o
440    }
441
442    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
443    /// nearest value of the specified precision. An [`Ordering`] is returned, indicating whether
444    /// the rounded value is less than, equal to, or greater than the exact value.
445    ///
446    /// See [`Float::log_base_10_prec_round`] for details and special cases.
447    ///
448    /// # Worst-case complexity
449    /// $T(n) = O(n (\log n)^2 \log\log n)$
450    ///
451    /// $M(n) = O(n (\log n)^2)$
452    ///
453    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
454    ///
455    /// # Panics
456    /// Panics if `prec` is zero.
457    ///
458    /// # Examples
459    /// ```
460    /// use malachite_float::Float;
461    /// use std::cmp::Ordering::*;
462    ///
463    /// let mut x = Float::from(1000);
464    /// let o = x.log_base_10_prec_assign(10);
465    /// assert_eq!(x.to_string(), "3.0000");
466    /// assert_eq!(o, Equal);
467    /// ```
468    #[inline]
469    pub fn log_base_10_prec_assign(&mut self, prec: u64) -> Ordering {
470        self.log_base_10_prec_round_assign(prec, Nearest)
471    }
472
473    /// Computes $\log_{10} x$, where $x$ is a [`Float`], in place, rounding the result to the
474    /// precision of the input and with the specified rounding mode. An [`Ordering`] is returned,
475    /// indicating whether the rounded value is less than, equal to, or greater than the exact
476    /// value.
477    ///
478    /// See [`Float::log_base_10_prec_round`] for details and special cases.
479    ///
480    /// # Worst-case complexity
481    /// $T(n) = O(n (\log n)^2 \log\log n)$
482    ///
483    /// $M(n) = O(n (\log n)^2)$
484    ///
485    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
486    ///
487    /// # Panics
488    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input's
489    /// precision.
490    ///
491    /// # Examples
492    /// ```
493    /// use malachite_base::rounding_modes::RoundingMode::*;
494    /// use malachite_float::Float;
495    /// use std::cmp::Ordering::*;
496    ///
497    /// let mut x = Float::from(100);
498    /// let o = x.log_base_10_round_assign(Nearest);
499    /// assert_eq!(x.to_string(), "2.00");
500    /// assert_eq!(o, Equal);
501    /// ```
502    #[inline]
503    pub fn log_base_10_round_assign(&mut self, rm: RoundingMode) -> Ordering {
504        let prec = self.significant_bits();
505        self.log_base_10_prec_round_assign(prec, rm)
506    }
507
508    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the specified
509    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
510    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
511    /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
512    /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
513    /// `Equal`.
514    ///
515    /// The base-10 logarithm of any negative number is `NaN`.
516    ///
517    /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
518    /// or too small to be representable as [`Float`]s. Neither overflow nor underflow of the output
519    /// is possible.
520    ///
521    /// See [`Float::log_base_10_prec_round`] for details and a description of the rounding
522    /// behavior.
523    ///
524    /// Special cases:
525    /// - $f(0,p,m)=-\infty$
526    /// - $f(x,p,m)=\text{NaN}$ for $x<0$
527    /// - $f(1,p,m)=0.0$, and the result is exact
528    /// - $f(10^n,p,m)=n$, rounded to precision $p$; the result is exact if and only if the integer
529    ///   $n$ is representable with precision $p$. This includes negative powers of 10 like $1/100$,
530    ///   and powers of 10 whose exponents lie far outside the exponent range of [`Float`].
531    ///
532    /// # Worst-case complexity
533    /// $T(n) = O(n (\log n)^2 \log\log n)$
534    ///
535    /// $M(n) = O(n (\log n)^2)$
536    ///
537    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
538    ///
539    /// # Panics
540    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
541    /// with the given precision. (The result is exactly representable if and only if $x \leq 0$ or
542    /// $x$ is a power of 10 whose base-10 logarithm is representable with the given precision.)
543    ///
544    /// # Examples
545    /// ```
546    /// use malachite_base::rounding_modes::RoundingMode::*;
547    /// use malachite_float::Float;
548    /// use malachite_q::Rational;
549    /// use std::cmp::Ordering::*;
550    ///
551    /// let (log, o) = Float::log_base_10_rational_prec_round(Rational::from(1000), 10, Exact);
552    /// assert_eq!(log.to_string(), "3.0000");
553    /// assert_eq!(o, Equal);
554    ///
555    /// let (log, o) =
556    ///     Float::log_base_10_rational_prec_round(Rational::from_signeds(1, 100), 10, Exact);
557    /// assert_eq!(log.to_string(), "-2.0000"); // log_10(1/100) = -2
558    /// assert_eq!(o, Equal);
559    /// ```
560    #[allow(clippy::needless_pass_by_value)]
561    #[inline]
562    pub fn log_base_10_rational_prec_round(
563        x: Rational,
564        prec: u64,
565        rm: RoundingMode,
566    ) -> (Self, Ordering) {
567        Self::log_base_10_rational_prec_round_ref(&x, prec, rm)
568    }
569
570    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the specified
571    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
572    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
573    /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
574    /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
575    /// `Equal`.
576    ///
577    /// See [`Float::log_base_10_rational_prec_round`] for details, special cases, and a description
578    /// of the rounding behavior.
579    ///
580    /// # Worst-case complexity
581    /// $T(n) = O(n (\log n)^2 \log\log n)$
582    ///
583    /// $M(n) = O(n (\log n)^2)$
584    ///
585    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
586    ///
587    /// # Panics
588    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
589    /// with the given precision.
590    ///
591    /// # Examples
592    /// ```
593    /// use malachite_base::rounding_modes::RoundingMode::*;
594    /// use malachite_float::Float;
595    /// use malachite_q::Rational;
596    /// use std::cmp::Ordering::*;
597    ///
598    /// let (log, o) =
599    ///     Float::log_base_10_rational_prec_round_ref(&Rational::from(1000), 10, Nearest);
600    /// assert_eq!(log.to_string(), "3.0000");
601    /// assert_eq!(o, Equal);
602    /// ```
603    pub fn log_base_10_rational_prec_round_ref(
604        x: &Rational,
605        prec: u64,
606        rm: RoundingMode,
607    ) -> (Self, Ordering) {
608        assert_ne!(prec, 0);
609        match x.sign() {
610            Equal => return (float_negative_infinity!(), Equal),
611            Less => return (float_nan!(), Equal),
612            Greater => {}
613        }
614        // If x = 10^m, then log_base_10(x) = m is an exact integer (m may be negative, for x < 1).
615        // The Ziv loop could never certify it (see float_is_power_of_10 for the Float analog).
616        if let Some(m) = x.checked_log_base(10) {
617            return Self::from_signed_prec_round(m, prec, rm);
618        }
619        // The result is irrational, so it is never exactly representable.
620        assert_ne!(rm, Exact, "Inexact log_base_10");
621        log_base_10_rational_prec_round_helper(x, prec, rm)
622    }
623
624    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the nearest
625    /// value of the specified precision and returning the result as a [`Float`]. The [`Rational`]
626    /// is taken by value. An [`Ordering`] is also returned, indicating whether the rounded value is
627    /// less than, equal to, or greater than the exact value.
628    ///
629    /// See [`Float::log_base_10_rational_prec_round`] for details and special cases.
630    ///
631    /// # Worst-case complexity
632    /// $T(n) = O(n (\log n)^2 \log\log n)$
633    ///
634    /// $M(n) = O(n (\log n)^2)$
635    ///
636    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
637    ///
638    /// # Panics
639    /// Panics if `prec` is zero.
640    ///
641    /// # Examples
642    /// ```
643    /// use malachite_float::Float;
644    /// use malachite_q::Rational;
645    /// use std::cmp::Ordering::*;
646    ///
647    /// let (log, o) = Float::log_base_10_rational_prec(Rational::from_signeds(1, 100), 10);
648    /// assert_eq!(log.to_string(), "-2.0000");
649    /// assert_eq!(o, Equal);
650    /// ```
651    #[inline]
652    pub fn log_base_10_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
653        Self::log_base_10_rational_prec_round(x, prec, Nearest)
654    }
655
656    /// Computes $\log_{10} x$, where $x$ is a [`Rational`], rounding the result to the nearest
657    /// value of the specified precision and returning the result as a [`Float`]. The [`Rational`]
658    /// is taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
659    /// value is less than, equal to, or greater than the exact value.
660    ///
661    /// See [`Float::log_base_10_rational_prec_round`] for details and special cases.
662    ///
663    /// # Worst-case complexity
664    /// $T(n) = O(n (\log n)^2 \log\log n)$
665    ///
666    /// $M(n) = O(n (\log n)^2)$
667    ///
668    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
669    ///
670    /// # Panics
671    /// Panics if `prec` is zero.
672    ///
673    /// # Examples
674    /// ```
675    /// use malachite_float::Float;
676    /// use malachite_q::Rational;
677    /// use std::cmp::Ordering::*;
678    ///
679    /// let (log, o) = Float::log_base_10_rational_prec_ref(&Rational::from(50), 10);
680    /// assert_eq!(log.to_string(), "1.6992");
681    /// assert_eq!(o, Greater);
682    /// ```
683    #[inline]
684    pub fn log_base_10_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
685        Self::log_base_10_rational_prec_round_ref(x, prec, Nearest)
686    }
687}
688
689impl LogBase10 for Float {
690    type Output = Self;
691
692    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
693    /// of the input's precision. The [`Float`] is taken by value.
694    ///
695    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
696    /// [`Float::log_base_10_prec_round`] for the special cases.
697    ///
698    /// $$
699    /// f(x) = \log_{10} x+\varepsilon,
700    /// $$
701    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_{10} x|\rfloor-p}$ and $p$ is the precision
702    /// of the input.
703    ///
704    /// # Worst-case complexity
705    /// $T(n) = O(n (\log n)^2 \log\log n)$
706    ///
707    /// $M(n) = O(n (\log n)^2)$
708    ///
709    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
710    ///
711    /// # Examples
712    /// ```
713    /// use malachite_base::num::arithmetic::traits::LogBase10;
714    /// use malachite_float::Float;
715    ///
716    /// assert_eq!(Float::from(1000).log_base_10().to_string(), "3.000");
717    /// assert_eq!(Float::from(100).log_base_10().to_string(), "2.00");
718    /// ```
719    #[inline]
720    fn log_base_10(self) -> Self {
721        let prec = self.significant_bits();
722        self.log_base_10_prec_round(prec, Nearest).0
723    }
724}
725
726impl LogBase10 for &Float {
727    type Output = Float;
728
729    /// Computes $\log_{10} x$, where $x$ is a [`Float`], rounding the result to the nearest value
730    /// of the input's precision. The [`Float`] is taken by reference.
731    ///
732    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
733    /// [`Float::log_base_10_prec_round`] for the special cases.
734    ///
735    /// $$
736    /// f(x) = \log_{10} x+\varepsilon,
737    /// $$
738    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_{10} x|\rfloor-p}$ and $p$ is the precision
739    /// of the input.
740    ///
741    /// # Worst-case complexity
742    /// $T(n) = O(n (\log n)^2 \log\log n)$
743    ///
744    /// $M(n) = O(n (\log n)^2)$
745    ///
746    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
747    ///
748    /// # Examples
749    /// ```
750    /// use malachite_base::num::arithmetic::traits::LogBase10;
751    /// use malachite_float::Float;
752    ///
753    /// assert_eq!((&Float::from(1000)).log_base_10().to_string(), "3.000");
754    /// ```
755    #[inline]
756    fn log_base_10(self) -> Float {
757        self.log_base_10_prec_round_ref(self.significant_bits(), Nearest)
758            .0
759    }
760}
761
762impl LogBase10Assign for Float {
763    /// Replaces a [`Float`] $x$ with $\log_{10} x$, rounding the result to the nearest value of the
764    /// input's precision.
765    ///
766    /// The base-10 logarithm of any nonzero negative number is `NaN`. See
767    /// [`Float::log_base_10_prec_round`] for the special cases.
768    ///
769    /// # Worst-case complexity
770    /// $T(n) = O(n (\log n)^2 \log\log n)$
771    ///
772    /// $M(n) = O(n (\log n)^2)$
773    ///
774    /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
775    ///
776    /// # Examples
777    /// ```
778    /// use malachite_base::num::arithmetic::traits::LogBase10Assign;
779    /// use malachite_float::Float;
780    ///
781    /// let mut x = Float::from(1000);
782    /// x.log_base_10_assign();
783    /// assert_eq!(x.to_string(), "3.000");
784    /// ```
785    #[inline]
786    fn log_base_10_assign(&mut self) {
787        let prec = self.significant_bits();
788        self.log_base_10_prec_round_assign(prec, Nearest);
789    }
790}
791
792/// Computes $\log_{10} x$, the base-10 logarithm of a primitive float. Using this function is more
793/// accurate than using the primitive float `log10` function (the standard library's `log10` is not
794/// always correctly rounded).
795///
796/// The base-10 logarithm of any negative number is `NaN`.
797///
798/// $$
799/// f(x) = \log_{10} x+\varepsilon.
800/// $$
801/// - If $\log_{10} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
802/// - If $\log_{10} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{10}
803///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
804///   if `T` is a [`f64`], but less if the output is subnormal).
805///
806/// Special cases:
807/// - $f(\text{NaN})=\text{NaN}$
808/// - $f(\infty)=\infty$
809/// - $f(-\infty)=\text{NaN}$
810/// - $f(\pm0.0)=-\infty$
811/// - $f(1.0)=0.0$
812/// - $f(x)=\text{NaN}$ for $x<0$
813///
814/// Neither overflow nor underflow is possible.
815///
816/// # Worst-case complexity
817/// Constant time and additional memory.
818///
819/// # Examples
820/// ```
821/// use malachite_base::num::basic::traits::NegativeInfinity;
822/// use malachite_base::num::float::NiceFloat;
823/// use malachite_float::float::arithmetic::log_base_10::primitive_float_log_base_10;
824///
825/// assert!(primitive_float_log_base_10(f32::NAN).is_nan());
826/// assert_eq!(
827///     NiceFloat(primitive_float_log_base_10(f32::INFINITY)),
828///     NiceFloat(f32::INFINITY)
829/// );
830/// assert_eq!(
831///     NiceFloat(primitive_float_log_base_10(0.0f32)),
832///     NiceFloat(f32::NEGATIVE_INFINITY)
833/// );
834/// // log_10(1000) = 3
835/// assert_eq!(
836///     NiceFloat(primitive_float_log_base_10(1000.0f32)),
837///     NiceFloat(3.0)
838/// );
839/// // log_10(50)
840/// assert_eq!(
841///     NiceFloat(primitive_float_log_base_10(50.0f32)),
842///     NiceFloat(1.69897)
843/// );
844/// assert!(primitive_float_log_base_10(-1.0f32).is_nan());
845/// ```
846#[inline]
847#[allow(clippy::type_repetition_in_bounds)]
848pub fn primitive_float_log_base_10<T: PrimitiveFloat>(x: T) -> T
849where
850    Float: From<T> + PartialOrd<T>,
851    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
852{
853    emulate_float_to_float_fn(Float::log_base_10_prec, x)
854}
855
856/// Computes $\log_{10} x$, the base-10 logarithm of a [`Rational`], returning a primitive float
857/// result.
858///
859/// If the logarithm is equidistant from two primitive floats, the primitive float with fewer 1s in
860/// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
861/// mode.
862///
863/// The base-10 logarithm of any negative number is `NaN`.
864///
865/// $$
866/// f(x) = \log_{10} x+\varepsilon.
867/// $$
868/// - If $\log_{10} x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
869/// - If $\log_{10} x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_{10}
870///   x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
871///   if `T` is a [`f64`], but less if the output is subnormal).
872///
873/// Special cases:
874/// - $f(0)=-\infty$
875/// - $f(x)=\text{NaN}$ for $x<0$
876/// - $f(1)=0.0$
877///
878/// Neither overflow nor underflow is possible.
879///
880/// # Worst-case complexity
881/// Constant time and additional memory.
882///
883/// # Examples
884/// ```
885/// use malachite_base::num::basic::traits::{NegativeInfinity, Zero};
886/// use malachite_base::num::float::NiceFloat;
887/// use malachite_float::float::arithmetic::log_base_10::primitive_float_log_base_10_rational;
888/// use malachite_q::Rational;
889///
890/// assert_eq!(
891///     NiceFloat(primitive_float_log_base_10_rational::<f64>(&Rational::ZERO)),
892///     NiceFloat(f64::NEGATIVE_INFINITY)
893/// );
894/// // log_10(1000) = 3
895/// assert_eq!(
896///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
897///         &Rational::from(1000)
898///     )),
899///     NiceFloat(3.0)
900/// );
901/// // log_10(1/3)
902/// assert_eq!(
903///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
904///         &Rational::from_unsigneds(1u8, 3)
905///     )),
906///     NiceFloat(-0.47712125471966244)
907/// );
908/// assert_eq!(
909///     NiceFloat(primitive_float_log_base_10_rational::<f64>(
910///         &Rational::from(-1000)
911///     )),
912///     NiceFloat(f64::NAN)
913/// );
914/// ```
915#[inline]
916#[allow(clippy::type_repetition_in_bounds)]
917pub fn primitive_float_log_base_10_rational<T: PrimitiveFloat>(x: &Rational) -> T
918where
919    Float: PartialOrd<T>,
920    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
921{
922    emulate_rational_to_float_fn(Float::log_base_10_rational_prec_ref, x)
923}