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}