malachite_float/float/arithmetic/log_base.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 alloc::vec::Vec;
24use core::cmp::Ordering::{self, *};
25use malachite_base::num::arithmetic::traits::{
26 CeilingLogBase2, CheckedLogBase, DivisibleBy, Gcd, IsPowerOf2, LogBase, LogBaseAssign, Mod,
27 ModAdd, ModMul, ModPow, Pow, Sign,
28};
29use malachite_base::num::basic::floats::PrimitiveFloat;
30use malachite_base::num::basic::integers::PrimitiveInt;
31use malachite_base::num::basic::traits::{One, Two, Zero as ZeroTrait};
32use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
33use malachite_base::num::factorization::traits::ExpressAsPower;
34use malachite_base::num::logic::traits::SignificantBits;
35use malachite_base::rounding_modes::RoundingMode::{self, *};
36use malachite_nz::integer::Integer;
37use malachite_nz::natural::Natural;
38use malachite_nz::natural::arithmetic::float_extras::float_can_round;
39use malachite_nz::platform::Limb;
40use malachite_q::Rational;
41
42// Decomposes a positive finite nonzero `Float` into `(s, t)` with value `s * 2^t` and `s` odd. `s`
43// has at most `prec` bits, so everything downstream of this decomposition works on small numbers no
44// matter how extreme `x`'s exponent is.
45pub(crate) fn odd_significand_and_exponent(x: &Float) -> (Natural, i64) {
46 let sig = x.significand_ref().unwrap();
47 let strip = sig.trailing_zeros().unwrap();
48 let s = sig >> strip;
49 let t = i64::from(x.get_exponent().unwrap()) - i64::exact_from(sig.significant_bits())
50 + i64::exact_from(strip);
51 (s, t)
52}
53
54// Given a positive dyadic value `s * 2^t` (`s` odd) and a root `2^z * h` (`h` an odd `Natural`, the
55// root positive and different from 1), returns the integer `m` with `s * 2^t = (2^z * h)^m`, or
56// `None` if no such integer exists.
57//
58// All arithmetic is on `s`, `h`, and `i64` exponents: nothing the size of `2^|t|` is ever
59// materialized, so the check is cheap for arbitrary exponents. `m` may be negative only when `h =
60// 1` (an odd `h >= 3` in the root makes every negative power non-dyadic).
61pub(crate) fn dyadic_log_of_root(s: &Natural, t: i64, z: i64, h: &Natural) -> Option<i64> {
62 if *h == 1u32 {
63 // The root is 2^z, so s * 2^t = 2^(z * m) requires s = 1 and z | t.
64 return if *s == 1u32 && z != 0 && t.divisible_by(z) {
65 Some(t / z)
66 } else {
67 None
68 };
69 }
70 // h >= 3: (2^z * h)^m = 2^(z * m) * h^m with h^m odd, so s = h^m and t = z * m. A negative m
71 // would put h in the denominator, which the dyadic s * 2^t cannot cancel, so m >= 0; and m = 0
72 // means the value is 1, which callers handle separately.
73 if *s == 1u32 {
74 return None;
75 }
76 let m = i64::exact_from(s.checked_log_base(h)?);
77 if z.checked_mul(m)? == t {
78 Some(m)
79 } else {
80 None
81 }
82}
83
84// Given a positive dyadic base `s_b * 2^t_b` (`s_b` odd) with base not 1, returns `(z, h, e_base)`
85// such that `base = (2^z * h)^e_base` with `h` odd and `e_base` maximal (the primitive root). All
86// work is on `s_b` (at most the base's precision in bits) and `i64` exponents, so the base is never
87// materialized as an integer or `Rational`, no matter how extreme its exponent.
88pub(crate) fn dyadic_primitive_root(s_b: &Natural, t_b: i64) -> (i64, Natural, u64) {
89 if *s_b == 1u32 {
90 // base = 2^t_b with t_b != 0: the primitive root is 2 (or 1/2 for a base below 1).
91 return if t_b > 0 {
92 (1, Natural::ONE, u64::exact_from(t_b))
93 } else {
94 (-1, Natural::ONE, u64::exact_from(-t_b))
95 };
96 }
97 // s_b = h0^k with k maximal (k = 1 when s_b is not a perfect power).
98 let (h0, k) = s_b.express_as_power().unwrap_or_else(|| (s_b.clone(), 1));
99 // base = h0^k * 2^t_b = (2^(t_b / e) * h0^(k / e))^e for any common divisor e of k and t_b; the
100 // primitive root takes e maximal.
101 let e = if t_b == 0 {
102 k
103 } else {
104 k.gcd(t_b.unsigned_abs())
105 };
106 (t_b / i64::exact_from(e), h0.pow(k / e), e)
107}
108
109// Given a positive `Rational` `g` other than 1, decomposes it as `g = 2^z * hn / hd` with `hn` and
110// `hd` odd (coprime) `Natural`s. At most one of the numerator and denominator is even, since they
111// are coprime.
112pub(crate) fn rational_root_parts(g: &Rational) -> (i64, Natural, Natural) {
113 let num = g.numerator_ref();
114 let den = g.denominator_ref();
115 let num_z = num.trailing_zeros().unwrap();
116 let den_z = den.trailing_zeros().unwrap();
117 (
118 i64::exact_from(num_z) - i64::exact_from(den_z),
119 num >> num_z,
120 den >> den_z,
121 )
122}
123
124// Given a positive dyadic value `x = s * 2^t` (`s` odd) and a `Rational` root `g != 1` (`g > 0`),
125// returns the integer `m` with `x = g^m`, or `None` if no such integer exists. Writing `g = 2^z *
126// hn / hd` with `hn`, `hd` odd and coprime: a positive `m` requires `hd = 1` (an odd denominator
127// could never cancel against the dyadic `x`), and a negative `m` symmetrically requires `hn = 1`,
128// in which case `x = (2^(-z) * hd)^(-m)`.
129pub(crate) fn dyadic_log_of_rational_root(s: &Natural, t: i64, g: &Rational) -> Option<i64> {
130 let (z, hn, hd) = rational_root_parts(g);
131 if hd == 1u32 {
132 dyadic_log_of_root(s, t, z, &hn)
133 } else if hn == 1u32 {
134 dyadic_log_of_root(s, t, -z, &hd).map(|m| -m)
135 } else {
136 // Both an odd numerator and an odd denominator: no nonzero power is dyadic.
137 None
138 }
139}
140
141// Given a positive `Rational` `x` and a root `2^z * h` (`h` an odd `Natural`, the root positive and
142// different from 1), returns the integer `m` with `x = (2^z * h)^m`, or `None` if no such integer
143// exists. All big-number work is on `x`'s odd numerator and denominator parts and on `h`; the
144// power-of-2 parts stay as `i64` exponents, so the root's 2-power is never materialized.
145pub(crate) fn rational_value_log_of_dyadic_root(x: &Rational, z: i64, h: &Natural) -> Option<i64> {
146 let num = x.numerator_ref();
147 let den = x.denominator_ref();
148 let num_z = num.trailing_zeros().unwrap();
149 let den_z = den.trailing_zeros().unwrap();
150 let v2 = i64::exact_from(num_z) - i64::exact_from(den_z);
151 let on = num >> num_z;
152 let od = den >> den_z;
153 if *h == 1u32 {
154 // The root is 2^z: x = 2^(z * m) requires odd parts 1 and z | v2.
155 return if on == 1u32 && od == 1u32 && z != 0 && v2.divisible_by(z) {
156 Some(v2 / z)
157 } else {
158 None
159 };
160 }
161 // h >= 3: a positive power puts h^m in the numerator, a negative one in the denominator.
162 if on != 1u32 && od == 1u32 {
163 let m = i64::exact_from(on.checked_log_base(h)?);
164 if z.checked_mul(m)? == v2 {
165 Some(m)
166 } else {
167 None
168 }
169 } else if on == 1u32 && od != 1u32 {
170 let m = i64::exact_from(od.checked_log_base(h)?);
171 if z.checked_mul(m)? == -v2 {
172 Some(-m)
173 } else {
174 None
175 }
176 } else {
177 // on = od = 1 means x is a power of 2, requiring m = 0 and hence x = 1 (callers handle);
178 // on, od > 1 cannot both come from a single power of h.
179 None
180 }
181}
182
183// A large prime modulus for the congruence filter in `dyadic_1p_log_of_root`: 2^64 - 59, the
184// largest 64-bit prime.
185const FILTER_PRIME: u64 = 0xFFFFFFFFFFFFFFC5;
186
187// Whether `n = h^m`, where `n` is only available as the implicit sum `high * 2^shift + low` (with
188// `shift` possibly enormous). A congruence modulo `FILTER_PRIME` proves inequality cheaply -- the
189// power and the shift reduce via modular exponentiation -- and only a match (in practice a genuine
190// power) is verified exactly, at cost proportional to `shift`.
191fn implicit_sum_is_pow(high: &Natural, shift: u64, low: &Integer, h: &Natural, m: u64) -> bool {
192 let p = Natural::from(FILTER_PRIME);
193 let lhs = (high % &p)
194 .mod_mul(Natural::TWO.mod_pow(Natural::from(shift), &p), &p)
195 .mod_add(Natural::exact_from(low.mod_op(Integer::from(&p))), &p);
196 if (h % &p).mod_pow(Natural::from(m), &p) != lhs {
197 return false;
198 }
199 // The filter passed; verify exactly.
200 Integer::from(high << shift) + low == h.pow(m)
201}
202
203// Given a `Float` `x` (finite, nonzero, greater than -1) and a root `2^z * h` (`h` an odd
204// `Natural`, the root positive and different from 1), returns the integer `m` with `1 + x = (2^z *
205// h)^m`, or `None` if no such integer exists.
206//
207// `1 + x` is never materialized up front: its bit length can be as large as `|EXP(x)|` (up to
208// ~2^30) even when `x` itself has few bits. Instead, the structure of `1 + x` -- an implicit sum
209// with an odd significand pinned by `x`'s own odd significand `s` and exponent `t` -- determines at
210// most a couple of candidate exponents `m`, each checked by a congruence filter that proves
211// non-powers unequal; the expensive exact verification runs only for a match, whose cost is
212// proportional to the true size of `1 + x`.
213pub(crate) fn dyadic_1p_log_of_root(x: &Float, z: i64, h: &Natural) -> Option<i64> {
214 let (s, t) = odd_significand_and_exponent(x);
215 let neg = *x < 0u32;
216 if t >= 0 {
217 // x is an integer; x > -1 and x != 0, so x >= 1 and 1 + x = s * 2^t + 1.
218 debug_assert!(!neg);
219 if t == 0 {
220 // 1 + x = s + 1 is small: decompose it and match directly.
221 let n = &s + Natural::ONE;
222 let r = n.trailing_zeros().unwrap();
223 return dyadic_log_of_root(&(n >> r), i64::exact_from(r), z, h);
224 }
225 // t > 0: 1 + x = s * 2^t + 1 is odd and greater than 1, so the root's power-of-2 part must
226 // vanish and h contributes a positive power.
227 if z != 0 || *h == 1u32 {
228 return None;
229 }
230 // 1 + x has bit length exactly t + bits(s). Each candidate m must reproduce it.
231 let l = u64::exact_from(t) + s.significant_bits();
232 for m in pow_bit_length_candidates(h, l) {
233 if implicit_sum_is_pow(&s, u64::exact_from(t), &Integer::ONE, h, m) {
234 return Some(i64::exact_from(m));
235 }
236 }
237 return None;
238 }
239 // t < 0: 1 + x = (2^|t| ± s) * 2^t, with an odd numerator n = 2^|t| - s (x < 0) or 2^|t| + s
240 // (x > 0). The 2-adic valuation of 1 + x is exactly t, so z * m = t.
241 let t_abs = u64::exact_from(-t);
242 if *h == 1u32 {
243 // Root 2^z: 1 + x = 2^(z * m) requires n = 1, i.e. x < 0 and s = 2^|t| - 1 (an all-ones odd
244 // number, checked without materializing 2^|t|).
245 return if neg
246 && z != 0
247 && t.divisible_by(z)
248 && s.significant_bits() == t_abs
249 && (&s + Natural::ONE).is_power_of_2()
250 {
251 Some(t / z)
252 } else {
253 None
254 };
255 }
256 if z == 0 || !t.divisible_by(z) {
257 // An odd root can't produce the nonzero 2-adic valuation t, and a mixed root needs z | t.
258 return None;
259 }
260 // The candidate exponent is pinned by the 2-adic valuation alone: n = h^m needs m >= 1, since n
261 // is a positive integer and n = 1 (forcing m = 0) was the h = 1 case above. The congruence
262 // filter then proves or refutes n = h^m without materializing n.
263 let m = t / z;
264 if m <= 0 {
265 return None;
266 }
267 let low = if neg {
268 -Integer::from(&s)
269 } else {
270 Integer::from(&s)
271 };
272 if implicit_sum_is_pow(&Natural::ONE, t_abs, &low, h, u64::exact_from(m)) {
273 Some(m)
274 } else {
275 None
276 }
277}
278
279// The integers `m` for which `h^m` (with `h` an odd `Natural` at least 3) can have bit length
280// exactly `l`: at most a couple of values, pinned by 80-bit directed bounds on `log_2(h)`.
281fn pow_bit_length_candidates(h: &Natural, l: u64) -> Vec<u64> {
282 // log_2(h) is irrational (h is odd and at least 3), so directed rounding gives strict bounds.
283 let h_float = Float::exact_from(h.clone());
284 let lo = Rational::exact_from(h_float.log_base_2_prec_round_ref(80, Floor).0);
285 let hi = Rational::exact_from(h_float.log_base_2_prec_round_ref(80, Ceiling).0);
286 // h^m has bit length l iff l - 1 <= m * log_2(h) < l.
287 let m_min = Integer::rounding_from(Rational::from(l - 1) / hi, Ceiling).0;
288 let m_max = Integer::rounding_from(Rational::from(l) / lo, Floor).0;
289 let mut candidates = Vec::new();
290 let mut m = m_min;
291 while m <= m_max && candidates.len() < 4 {
292 if m > 0u32 {
293 candidates.push(u64::exact_from(&m));
294 }
295 m += Integer::ONE;
296 }
297 candidates
298}
299
300// `log_base(x)` is rational exactly when `x` and `base` are both powers of a common root `g`, say
301// `x = g ^ m` and `base = g ^ e_base`; then `log_base(x) = m / e_base`. Taking `g` to be the
302// smallest integer of which `base` is a power (obtained by stripping `base` of perfect-power
303// factors via `express_as_power`) and writing `g = 2^z * h` with `h` odd, this holds iff `x`'s odd
304// significand is the corresponding power of `h` and its exponent matches (see
305// `dyadic_log_of_root`).
306//
307// Detecting these rational results up front is essential, not just an optimization: when the result
308// is exactly representable (for example `log_9(3) = 1/2`), the Ziv loop in
309// `log_base_prec_round_normal` would never terminate, because the rounding test can never certify a
310// value that sits exactly on a representable point (or exactly on a tie). This generalizes the
311// `10^n` exactness check in mpfr_log10, which only catches integer results.
312//
313// The check is complete and cheap for any input: representable results can have enormous exponents
314// with few significant bits (`log_4` of the smallest positive `Float` is `-2^29`, exact at
315// precision 1), so no size cutoff on `x`'s exponent is sound; instead the decomposition keeps all
316// big-number work on `x`'s odd significand, which has at most `prec(x)` bits.
317pub(crate) fn rational_log_base(x: &Float, base: u64) -> Option<Rational> {
318 // `express_as_power` returns `None` when `base` is not a perfect power, in which case `base`
319 // itself is `g` (with exponent 1).
320 let (g, e_base) = base.express_as_power().unwrap_or((base, 1));
321 let z = i64::exact_from(g.trailing_zeros());
322 let h = Natural::from(g >> g.trailing_zeros());
323 let (s, t) = odd_significand_and_exponent(x);
324 let m = dyadic_log_of_root(&s, t, z, &h)?;
325 Some(Rational::from_signeds(m, i64::exact_from(e_base)))
326}
327
328// Returns `Some(m / e_base)` -- the value of `log_base(x)` -- when the positive `Rational` `x`
329// equals `g ^ m` for the root `g` of `base` (so `base = g ^ e_base` and `log_base(x)` is rational),
330// and `None` when `log_base(x)` is irrational. `x` must be positive and `base > 1`.
331//
332// `m` (signed) is found by `Rational::checked_log_base`, which also covers `x < 1` (negative `m`).
333// Detecting these rational results up front is essential: the Ziv loop could never certify an
334// exactly-representable one (see `rational_log_base` for the `Float` analog).
335pub(crate) fn rational_log_base_of_rational(x: &Rational, base: u64) -> Option<Rational> {
336 let (g, e_base) = base.express_as_power().unwrap_or((base, 1));
337 x.checked_log_base(g)
338 .map(|m| Rational::from_signeds(m, i64::exact_from(e_base)))
339}
340
341// The computation of log_base(x, base) is done by log_base(x) = ln(x) / ln(base). When `base` is a
342// power of 2 the caller delegates to `log_base_power_of_2`, so here `base` is not a power of 2.
343//
344// This is mpfr_log10 from log10.c, MPFR 4.3.0, generalized from base 10 to an arbitrary non-power-
345// of-2 `base`. The input is finite, nonzero, and positive.
346fn log_base_prec_round_normal(
347 x: &Float,
348 base: u64,
349 prec: u64,
350 rm: RoundingMode,
351) -> (Float, Ordering) {
352 // If x is 1, the result is 0.
353 if *x == 1u32 {
354 return (Float::ZERO, Equal);
355 }
356 // If log_base(x) is rational -- x and base are both powers of a common integer -- compute it
357 // directly. This includes the exactly-representable results (integers like log_8(64) = 2 and
358 // dyadics like log_9(3) = 1/2), which the Ziv loop below could never certify, as well as
359 // non-representable rationals like log_27(9) = 2/3, which it could but for which the direct
360 // computation is cheaper and exact.
361 if let Some(q) = rational_log_base(x, base) {
362 return Float::from_rational_prec_round(q, prec, rm);
363 }
364 // log_base(x) for x in a sliver of 1 can fall below the smallest positive Float; the 1-plus-x
365 // form handles that underflow region.
366 match sliver_of_one(x) {
367 SliverOfOne::Representable(d) => return d.log_base_1_plus_x_prec_round(base, prec, rm),
368 SliverOfOne::Underflow => {
369 return Float::log_base_rational_prec_round(Rational::exact_from(x), base, prec, rm);
370 }
371 SliverOfOne::No => {}
372 }
373 // The result is irrational, so it is never exactly representable.
374 assert_ne!(rm, Exact, "Inexact log_base");
375 let base_float = Float::from(base);
376 // Compute the precision of the intermediary variable: the optimal number of bits, see
377 // algorithms.tex.
378 let mut working_prec = prec + 4 + prec.ceiling_log_base_2();
379 let mut increment = Limb::WIDTH;
380 loop {
381 // ln(x) / ln(base). ln(x), ln(base), and the division are each correctly rounded (at most
382 // 1/2 ulp), so the relative error is below 2^(2 - working_prec) and working_prec - 4
383 // correct bits suffice for rounding (mpfr_log10 uses Nt - 4).
384 let t = x
385 .ln_prec_ref(working_prec)
386 .0
387 .div_prec(base_float.ln_prec_ref(working_prec).0, working_prec)
388 .0;
389 if float_can_round(t.significand_ref().unwrap(), working_prec - 4, prec, rm) {
390 return Float::from_float_prec_round(t, prec, rm);
391 }
392 // Increase the precision.
393 working_prec += increment;
394 increment = working_prec >> 1;
395 }
396}
397
398// Computes log_base(x) for a positive `Rational` x whose logarithm is irrational, in a Ziv loop.
399// `base > 1` is not a power of 2.
400//
401// log_base(x) = log_2(x) / log_2(base). Routing through `log_base_2_rational` (rather than
402// computing `ln(x) / ln(base)` directly) reuses its handling of x near a power of 2 -- in
403// particular x near 1, where the result is near 0 and a direct computation would need a working
404// precision proportional to how close x is to 1. log_2(x), log_2(base), and the division are each
405// correctly rounded (at most 1/2 ulp), so the relative error is below 2^(2 - working_prec) and
406// working_prec - 4 correct bits suffice for rounding.
407fn log_base_rational_prec_round_helper(
408 x: &Rational,
409 base: u64,
410 prec: u64,
411 rm: RoundingMode,
412) -> (Float, Ordering) {
413 let base_float = Float::from(base);
414 // The initial slack keeps working_prec at least 7, so the working_prec - 6 below stays
415 // positive.
416 let mut working_prec = prec + 6 + prec.ceiling_log_base_2();
417 let mut increment = Limb::WIDTH;
418 loop {
419 // log_2(x) in the extended exponent range: for x within a sliver of 1 the ordinary Float
420 // form would flush to zero or clamp, and the rounding test below could never resolve it.
421 let num = extended_log_base_2_of_rational(x, working_prec);
422 let den = ExtendedFloat::from(base_float.log_base_2_prec_ref(working_prec).0);
423 let quotient = num.div_prec_val_ref(&den, working_prec).0;
424 // log_2(x) is within 2 ulps, log_2(base) within 1/2, and the division adds 1/2 more, so
425 // working_prec - 6 correct bits comfortably suffice.
426 if float_can_round(
427 quotient.x.significand_ref().unwrap(),
428 working_prec - 6,
429 prec,
430 rm,
431 ) {
432 let (rounded, o) = Float::from_float_prec_round(quotient.x, prec, rm);
433 let mut result = ExtendedFloat::from(rounded);
434 result.exp = result.exp.checked_add(quotient.exp).unwrap();
435 return result.into_float_helper(prec, rm, o);
436 }
437 // Increase the precision.
438 working_prec += increment;
439 increment = working_prec >> 1;
440 }
441}
442
443impl Float {
444 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
445 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
446 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded value is
447 /// less than, equal to, or greater than the exact value. Although `NaN`s are not comparable to
448 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
449 ///
450 /// The base-$b$ logarithm of any nonzero negative number is `NaN`.
451 ///
452 /// When `base` is a power of 2, this function delegates to
453 /// [`Float::log_base_power_of_2_prec_round`]; otherwise it computes $\ln x / \ln b$.
454 ///
455 /// See [`RoundingMode`] for a description of the possible rounding modes.
456 ///
457 /// $$
458 /// f(x,b,p,m) = \log_b x+\varepsilon.
459 /// $$
460 /// - If $\log_b x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
461 /// 0.
462 /// - If $\log_b x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
463 /// 2^{\lfloor\log_2 |\log_b x|\rfloor-p+1}$.
464 /// - If $\log_b x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
465 /// 2^{\lfloor\log_2 |\log_b x|\rfloor-p}$.
466 ///
467 /// If the output has a precision, it is `prec`.
468 ///
469 /// Special cases:
470 /// - $f(\text{NaN},b,p,m)=\text{NaN}$
471 /// - $f(\infty,b,p,m)=\infty$
472 /// - $f(-\infty,b,p,m)=\text{NaN}$
473 /// - $f(\pm0.0,b,p,m)=-\infty$
474 /// - $f(1.0,b,p,m)=0.0$, and the result is exact
475 /// - $f(b^n,b,p,m)=n$, rounded to precision $p$; the result is exact if and only if $n$ is
476 /// representable with precision $p$
477 /// - $f(x,b,p,m)=\text{NaN}$ for $x<0$
478 ///
479 /// Neither overflow nor underflow is possible.
480 ///
481 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_prec`] instead. If
482 /// you know that your target precision is the precision of the input, consider using
483 /// [`Float::log_base_round`] instead. If both of these things are true, consider using
484 /// [`Float::log_base`] instead.
485 ///
486 /// # Worst-case complexity
487 /// $T(n) = O(n (\log n)^2 \log\log n)$
488 ///
489 /// $M(n) = O(n (\log n)^2)$
490 ///
491 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
492 ///
493 /// # Panics
494 /// Panics if `prec` is zero, if `base` is less than 2, or if `rm` is `Exact` but the result
495 /// cannot be represented exactly with the given 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 (log, o) = Float::from(1000).log_base_prec_round(10, 10, Nearest);
504 /// assert_eq!(log.to_string(), "3.0000");
505 /// assert_eq!(o, Equal);
506 ///
507 /// let (log, o) = Float::from(50).log_base_prec_round(10, 10, Floor);
508 /// assert_eq!(log.to_string(), "1.6973");
509 /// assert_eq!(o, Less);
510 ///
511 /// let (log, o) = Float::from(50).log_base_prec_round(10, 10, Ceiling);
512 /// assert_eq!(log.to_string(), "1.6992");
513 /// assert_eq!(o, Greater);
514 /// ```
515 #[inline]
516 pub fn log_base_prec_round(self, base: u64, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
517 assert_ne!(prec, 0);
518 assert!(base > 1, "Logarithm base must be greater than 1");
519 if base.is_power_of_2() {
520 return self.log_base_power_of_2_prec_round(i64::from(base.trailing_zeros()), prec, rm);
521 }
522 match self {
523 Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
524 (float_nan!(), Equal)
525 }
526 float_either_zero!() => (float_negative_infinity!(), Equal),
527 float_infinity!() => (float_infinity!(), Equal),
528 _ => log_base_prec_round_normal(&self, base, prec, rm),
529 }
530 }
531
532 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
533 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
534 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded value
535 /// is less than, equal to, or greater than the exact value. Although `NaN`s are not comparable
536 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
537 ///
538 /// See [`Float::log_base_prec_round`] for details, special cases, and a description of the
539 /// rounding behavior.
540 ///
541 /// # Worst-case complexity
542 /// $T(n) = O(n (\log n)^2 \log\log n)$
543 ///
544 /// $M(n) = O(n (\log n)^2)$
545 ///
546 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
547 ///
548 /// # Panics
549 /// Panics if `prec` is zero, if `base` is less than 2, or if `rm` is `Exact` but the result
550 /// cannot be represented exactly with the given precision.
551 ///
552 /// # Examples
553 /// ```
554 /// use malachite_base::rounding_modes::RoundingMode::*;
555 /// use malachite_float::Float;
556 /// use std::cmp::Ordering::*;
557 ///
558 /// let (log, o) = Float::from(1000).log_base_prec_round_ref(10, 10, Nearest);
559 /// assert_eq!(log.to_string(), "3.0000");
560 /// assert_eq!(o, Equal);
561 /// ```
562 #[inline]
563 pub fn log_base_prec_round_ref(
564 &self,
565 base: u64,
566 prec: u64,
567 rm: RoundingMode,
568 ) -> (Self, Ordering) {
569 assert_ne!(prec, 0);
570 assert!(base > 1, "Logarithm base must be greater than 1");
571 if base.is_power_of_2() {
572 return self.log_base_power_of_2_prec_round_ref(
573 i64::from(base.trailing_zeros()),
574 prec,
575 rm,
576 );
577 }
578 match self {
579 Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
580 (float_nan!(), Equal)
581 }
582 float_either_zero!() => (float_negative_infinity!(), Equal),
583 float_infinity!() => (float_infinity!(), Equal),
584 _ => log_base_prec_round_normal(self, base, prec, rm),
585 }
586 }
587
588 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
589 /// the result to the nearest value of the specified precision. The [`Float`] is taken by value.
590 /// An [`Ordering`] is also returned, indicating whether the rounded value is less than, equal
591 /// to, or greater than the exact value.
592 ///
593 /// See [`Float::log_base_prec_round`] for details and special cases.
594 ///
595 /// # Worst-case complexity
596 /// $T(n) = O(n (\log n)^2 \log\log n)$
597 ///
598 /// $M(n) = O(n (\log n)^2)$
599 ///
600 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
601 ///
602 /// # Panics
603 /// Panics if `prec` is zero or if `base` is less than 2.
604 ///
605 /// # Examples
606 /// ```
607 /// use malachite_float::Float;
608 /// use std::cmp::Ordering::*;
609 ///
610 /// let (log, o) = Float::from(50).log_base_prec(10, 10);
611 /// assert_eq!(log.to_string(), "1.6992");
612 /// assert_eq!(o, Greater);
613 /// ```
614 #[inline]
615 pub fn log_base_prec(self, base: u64, prec: u64) -> (Self, Ordering) {
616 self.log_base_prec_round(base, prec, Nearest)
617 }
618
619 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
620 /// the result to the nearest value of the specified precision. The [`Float`] is taken by
621 /// reference. An [`Ordering`] is also returned, indicating whether the rounded value is less
622 /// than, equal to, or greater than the exact value.
623 ///
624 /// See [`Float::log_base_prec_round`] for details and special cases.
625 ///
626 /// # Worst-case complexity
627 /// $T(n) = O(n (\log n)^2 \log\log n)$
628 ///
629 /// $M(n) = O(n (\log n)^2)$
630 ///
631 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
632 ///
633 /// # Panics
634 /// Panics if `prec` is zero or if `base` is less than 2.
635 ///
636 /// # Examples
637 /// ```
638 /// use malachite_float::Float;
639 /// use std::cmp::Ordering::*;
640 ///
641 /// let (log, o) = Float::from(50).log_base_prec_ref(10, 10);
642 /// assert_eq!(log.to_string(), "1.6992");
643 /// assert_eq!(o, Greater);
644 /// ```
645 #[inline]
646 pub fn log_base_prec_ref(&self, base: u64, prec: u64) -> (Self, Ordering) {
647 self.log_base_prec_round_ref(base, prec, Nearest)
648 }
649
650 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
651 /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
652 /// is taken by value. An [`Ordering`] is also returned, indicating whether the rounded value is
653 /// less than, equal to, or greater than the exact value.
654 ///
655 /// See [`Float::log_base_prec_round`] for details and special cases.
656 ///
657 /// # Worst-case complexity
658 /// $T(n) = O(n (\log n)^2 \log\log n)$
659 ///
660 /// $M(n) = O(n (\log n)^2)$
661 ///
662 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
663 ///
664 /// # Panics
665 /// Panics if `base` is less than 2, or if `rm` is `Exact` but the result cannot be represented
666 /// exactly with the input's precision.
667 ///
668 /// # Examples
669 /// ```
670 /// use malachite_base::rounding_modes::RoundingMode::*;
671 /// use malachite_float::Float;
672 /// use std::cmp::Ordering::*;
673 ///
674 /// let (log, o) = Float::from(1000).log_base_round(10, Floor);
675 /// assert_eq!(log.to_string(), "3.000");
676 /// assert_eq!(o, Equal);
677 /// ```
678 #[inline]
679 pub fn log_base_round(self, base: u64, rm: RoundingMode) -> (Self, Ordering) {
680 let prec = self.significant_bits();
681 self.log_base_prec_round(base, prec, rm)
682 }
683
684 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
685 /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
686 /// is taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
687 /// value is less than, equal to, or greater than the exact value.
688 ///
689 /// See [`Float::log_base_prec_round`] for details and special cases.
690 ///
691 /// # Worst-case complexity
692 /// $T(n) = O(n (\log n)^2 \log\log n)$
693 ///
694 /// $M(n) = O(n (\log n)^2)$
695 ///
696 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
697 ///
698 /// # Panics
699 /// Panics if `base` is less than 2, or if `rm` is `Exact` but the result cannot be represented
700 /// exactly with the input's precision.
701 ///
702 /// # Examples
703 /// ```
704 /// use malachite_base::rounding_modes::RoundingMode::*;
705 /// use malachite_float::Float;
706 /// use std::cmp::Ordering::*;
707 ///
708 /// let (log, o) = Float::from(81).log_base_round_ref(3, Ceiling);
709 /// assert_eq!(log.to_string(), "4.000");
710 /// assert_eq!(o, Equal);
711 /// ```
712 #[inline]
713 pub fn log_base_round_ref(&self, base: u64, rm: RoundingMode) -> (Self, Ordering) {
714 self.log_base_prec_round_ref(base, self.significant_bits(), rm)
715 }
716
717 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, in place,
718 /// rounding the result to the specified precision and with the specified rounding mode. An
719 /// [`Ordering`] is returned, indicating whether the rounded value is less than, equal to, or
720 /// greater than the exact value.
721 ///
722 /// See [`Float::log_base_prec_round`] for details and special cases.
723 ///
724 /// # Worst-case complexity
725 /// $T(n) = O(n (\log n)^2 \log\log n)$
726 ///
727 /// $M(n) = O(n (\log n)^2)$
728 ///
729 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
730 ///
731 /// # Panics
732 /// Panics if `prec` is zero, if `base` is less than 2, or if `rm` is `Exact` but the result
733 /// cannot be represented exactly with the given precision.
734 ///
735 /// # Examples
736 /// ```
737 /// use malachite_base::rounding_modes::RoundingMode::*;
738 /// use malachite_float::Float;
739 /// use std::cmp::Ordering::*;
740 ///
741 /// let mut x = Float::from(50);
742 /// let o = x.log_base_prec_round_assign(10, 10, Floor);
743 /// assert_eq!(x.to_string(), "1.6973");
744 /// assert_eq!(o, Less);
745 /// ```
746 #[inline]
747 pub fn log_base_prec_round_assign(
748 &mut self,
749 base: u64,
750 prec: u64,
751 rm: RoundingMode,
752 ) -> Ordering {
753 let (result, o) = core::mem::take(self).log_base_prec_round(base, prec, rm);
754 *self = result;
755 o
756 }
757
758 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, in place,
759 /// rounding the result to the nearest value of the specified precision. An [`Ordering`] is
760 /// returned, indicating whether the rounded value is less than, equal to, or greater than the
761 /// exact value.
762 ///
763 /// See [`Float::log_base_prec_round`] for details and special cases.
764 ///
765 /// # Worst-case complexity
766 /// $T(n) = O(n (\log n)^2 \log\log n)$
767 ///
768 /// $M(n) = O(n (\log n)^2)$
769 ///
770 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
771 ///
772 /// # Panics
773 /// Panics if `prec` is zero or if `base` is less than 2.
774 ///
775 /// # Examples
776 /// ```
777 /// use malachite_float::Float;
778 /// use std::cmp::Ordering::*;
779 ///
780 /// let mut x = Float::from(1000);
781 /// let o = x.log_base_prec_assign(10, 10);
782 /// assert_eq!(x.to_string(), "3.0000");
783 /// assert_eq!(o, Equal);
784 /// ```
785 #[inline]
786 pub fn log_base_prec_assign(&mut self, base: u64, prec: u64) -> Ordering {
787 self.log_base_prec_round_assign(base, prec, Nearest)
788 }
789
790 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, in place,
791 /// rounding the result to the precision of the input and with the specified rounding mode. An
792 /// [`Ordering`] is returned, indicating whether the rounded value is less than, equal to, or
793 /// greater than the exact value.
794 ///
795 /// See [`Float::log_base_prec_round`] for details and special cases.
796 ///
797 /// # Worst-case complexity
798 /// $T(n) = O(n (\log n)^2 \log\log n)$
799 ///
800 /// $M(n) = O(n (\log n)^2)$
801 ///
802 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
803 ///
804 /// # Panics
805 /// Panics if `base` is less than 2, or if `rm` is `Exact` but the result cannot be represented
806 /// exactly with the input's precision.
807 ///
808 /// # Examples
809 /// ```
810 /// use malachite_base::rounding_modes::RoundingMode::*;
811 /// use malachite_float::Float;
812 /// use std::cmp::Ordering::*;
813 ///
814 /// let mut x = Float::from(81);
815 /// let o = x.log_base_round_assign(3, Nearest);
816 /// assert_eq!(x.to_string(), "4.000");
817 /// assert_eq!(o, Equal);
818 /// ```
819 #[inline]
820 pub fn log_base_round_assign(&mut self, base: u64, rm: RoundingMode) -> Ordering {
821 let prec = self.significant_bits();
822 self.log_base_prec_round_assign(base, prec, rm)
823 }
824
825 /// Computes $\log_b x$, where $x$ is a [`Rational`] and $b$ is a `u64` greater than 1, rounding
826 /// the result to the specified precision and with the specified rounding mode and returning the
827 /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
828 /// indicating whether the rounded value is less than, equal to, or greater than the exact
829 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
830 /// `NaN` it also returns `Equal`.
831 ///
832 /// The base-$b$ logarithm of any negative number is `NaN`.
833 ///
834 /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
835 /// or too small to be representable as [`Float`]s. Neither overflow nor underflow of the output
836 /// is possible.
837 ///
838 /// When `base` is a power of 2, this function delegates to
839 /// [`Float::log_base_power_of_2_rational_prec_round`].
840 ///
841 /// See [`Float::log_base_prec_round`] for details and a description of the rounding behavior.
842 ///
843 /// Special cases:
844 /// - $f(0,b,p,m)=-\infty$
845 /// - $f(x,b,p,m)=\text{NaN}$ for $x<0$
846 /// - $f(1,b,p,m)=0.0$, and the result is exact
847 ///
848 /// # Worst-case complexity
849 /// $T(n) = O(n (\log n)^2 \log\log n)$
850 ///
851 /// $M(n) = O(n (\log n)^2)$
852 ///
853 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
854 ///
855 /// # Panics
856 /// Panics if `prec` is zero, if `base` is less than 2, or if `rm` is `Exact` but the result
857 /// cannot be represented exactly with the given precision. (The result is exactly representable
858 /// if and only if $x \leq 0$ or $\log_b x$ is rational and representable with the given
859 /// precision.)
860 ///
861 /// # Examples
862 /// ```
863 /// use malachite_base::rounding_modes::RoundingMode::*;
864 /// use malachite_float::Float;
865 /// use malachite_q::Rational;
866 /// use std::cmp::Ordering::*;
867 ///
868 /// let (log, o) = Float::log_base_rational_prec_round(Rational::from(3), 9, 10, Exact);
869 /// assert_eq!(log.to_string(), "0.50000"); // log_9(3) = 1/2
870 /// assert_eq!(o, Equal);
871 ///
872 /// let (log, o) = Float::log_base_rational_prec_round(Rational::from(2), 3, 20, Nearest);
873 /// assert_eq!(log.to_string(), "0.63092995");
874 /// assert_eq!(o, Greater);
875 /// ```
876 #[allow(clippy::needless_pass_by_value)]
877 #[inline]
878 pub fn log_base_rational_prec_round(
879 x: Rational,
880 base: u64,
881 prec: u64,
882 rm: RoundingMode,
883 ) -> (Self, Ordering) {
884 Self::log_base_rational_prec_round_ref(&x, base, prec, rm)
885 }
886
887 /// Computes $\log_b x$, where $x$ is a [`Rational`] and $b$ is a `u64` greater than 1, rounding
888 /// the result to the specified precision and with the specified rounding mode and returning the
889 /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
890 /// returned, indicating whether the rounded value is less than, equal to, or greater than the
891 /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
892 /// returns a `NaN` it also returns `Equal`.
893 ///
894 /// See [`Float::log_base_rational_prec_round`] for details, special cases, and a description of
895 /// the rounding behavior.
896 ///
897 /// # Worst-case complexity
898 /// $T(n) = O(n (\log n)^2 \log\log n)$
899 ///
900 /// $M(n) = O(n (\log n)^2)$
901 ///
902 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
903 ///
904 /// # Panics
905 /// Panics if `prec` is zero, if `base` is less than 2, or if `rm` is `Exact` but the result
906 /// cannot be represented exactly with the given precision.
907 ///
908 /// # Examples
909 /// ```
910 /// use malachite_base::rounding_modes::RoundingMode::*;
911 /// use malachite_float::Float;
912 /// use malachite_q::Rational;
913 /// use std::cmp::Ordering::*;
914 ///
915 /// let (log, o) =
916 /// Float::log_base_rational_prec_round_ref(&Rational::from_signeds(1, 9), 3, 10, Exact);
917 /// assert_eq!(log.to_string(), "-2.0000"); // log_3(1/9) = -2
918 /// assert_eq!(o, Equal);
919 /// ```
920 pub fn log_base_rational_prec_round_ref(
921 x: &Rational,
922 base: u64,
923 prec: u64,
924 rm: RoundingMode,
925 ) -> (Self, Ordering) {
926 assert_ne!(prec, 0);
927 assert!(base > 1, "Logarithm base must be greater than 1");
928 if base.is_power_of_2() {
929 return Self::log_base_power_of_2_rational_prec_round_ref(
930 x,
931 i64::from(base.trailing_zeros()),
932 prec,
933 rm,
934 );
935 }
936 match x.sign() {
937 Equal => return (float_negative_infinity!(), Equal),
938 Less => return (float_nan!(), Equal),
939 Greater => {}
940 }
941 // If x = g^m for the base's root g (so base = g^e_base), then log_base(x) = m / e_base is
942 // rational, and exact -- the Ziv loop could never certify it (see rational_log_base).
943 if let Some(q) = rational_log_base_of_rational(x, base) {
944 return Self::from_rational_prec_round(q, prec, rm);
945 }
946 // The result is irrational, so it is never exactly representable.
947 assert_ne!(rm, Exact, "Inexact log_base");
948 log_base_rational_prec_round_helper(x, base, prec, rm)
949 }
950
951 /// Computes $\log_b x$, where $x$ is a [`Rational`] and $b$ is a `u64` greater than 1, rounding
952 /// the result to the nearest value of the specified precision and returning the result as a
953 /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
954 /// whether the rounded value is less than, equal to, or greater than the exact value.
955 ///
956 /// See [`Float::log_base_rational_prec_round`] for details and special cases.
957 ///
958 /// # Worst-case complexity
959 /// $T(n) = O(n (\log n)^2 \log\log n)$
960 ///
961 /// $M(n) = O(n (\log n)^2)$
962 ///
963 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
964 ///
965 /// # Panics
966 /// Panics if `prec` is zero or if `base` is less than 2.
967 ///
968 /// # Examples
969 /// ```
970 /// use malachite_float::Float;
971 /// use malachite_q::Rational;
972 /// use std::cmp::Ordering::*;
973 ///
974 /// let (log, o) = Float::log_base_rational_prec(Rational::from_signeds(1, 9), 3, 10);
975 /// assert_eq!(log.to_string(), "-2.0000");
976 /// assert_eq!(o, Equal);
977 /// ```
978 #[inline]
979 pub fn log_base_rational_prec(x: Rational, base: u64, prec: u64) -> (Self, Ordering) {
980 Self::log_base_rational_prec_round(x, base, prec, Nearest)
981 }
982
983 /// Computes $\log_b x$, where $x$ is a [`Rational`] and $b$ is a `u64` greater than 1, rounding
984 /// the result to the nearest value of the specified precision and returning the result as a
985 /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
986 /// indicating whether the rounded value is less than, equal to, or greater than the exact
987 /// value.
988 ///
989 /// See [`Float::log_base_rational_prec_round`] for details and special cases.
990 ///
991 /// # Worst-case complexity
992 /// $T(n) = O(n (\log n)^2 \log\log n)$
993 ///
994 /// $M(n) = O(n (\log n)^2)$
995 ///
996 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
997 ///
998 /// # Panics
999 /// Panics if `prec` is zero or if `base` is less than 2.
1000 ///
1001 /// # Examples
1002 /// ```
1003 /// use malachite_float::Float;
1004 /// use malachite_q::Rational;
1005 /// use std::cmp::Ordering::*;
1006 ///
1007 /// let (log, o) = Float::log_base_rational_prec_ref(&Rational::from(2), 3, 20);
1008 /// assert_eq!(log.to_string(), "0.63092995");
1009 /// assert_eq!(o, Greater);
1010 /// ```
1011 #[inline]
1012 pub fn log_base_rational_prec_ref(x: &Rational, base: u64, prec: u64) -> (Self, Ordering) {
1013 Self::log_base_rational_prec_round_ref(x, base, prec, Nearest)
1014 }
1015}
1016
1017impl LogBase<u64> for Float {
1018 type Output = Self;
1019
1020 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
1021 /// the result to the nearest value of the input's precision. The [`Float`] is taken by value.
1022 ///
1023 /// The base-$b$ logarithm of any nonzero negative number is `NaN`. See
1024 /// [`Float::log_base_prec_round`] for the special cases.
1025 ///
1026 /// $$
1027 /// f(x,b) = \log_b x+\varepsilon,
1028 /// $$
1029 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_b x|\rfloor-p}$ and $p$ is the precision of
1030 /// the input.
1031 ///
1032 /// # Worst-case complexity
1033 /// $T(n) = O(n (\log n)^2 \log\log n)$
1034 ///
1035 /// $M(n) = O(n (\log n)^2)$
1036 ///
1037 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
1038 ///
1039 /// # Panics
1040 /// Panics if `base` is less than 2.
1041 ///
1042 /// # Examples
1043 /// ```
1044 /// use malachite_base::num::arithmetic::traits::LogBase;
1045 /// use malachite_float::Float;
1046 ///
1047 /// assert_eq!(Float::from(1000).log_base(10).to_string(), "3.000");
1048 /// assert_eq!(Float::from(81).log_base(3).to_string(), "4.000");
1049 /// ```
1050 #[inline]
1051 fn log_base(self, base: u64) -> Self {
1052 let prec = self.significant_bits();
1053 self.log_base_prec_round(base, prec, Nearest).0
1054 }
1055}
1056
1057impl LogBase<u64> for &Float {
1058 type Output = Float;
1059
1060 /// Computes $\log_b x$, where $x$ is a [`Float`] and $b$ is a `u64` greater than 1, rounding
1061 /// the result to the nearest value of the input's precision. The [`Float`] is taken by
1062 /// reference.
1063 ///
1064 /// The base-$b$ logarithm of any nonzero negative number is `NaN`. See
1065 /// [`Float::log_base_prec_round`] for the special cases.
1066 ///
1067 /// $$
1068 /// f(x,b) = \log_b x+\varepsilon,
1069 /// $$
1070 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_b x|\rfloor-p}$ and $p$ is the precision of
1071 /// the input.
1072 ///
1073 /// # Worst-case complexity
1074 /// $T(n) = O(n (\log n)^2 \log\log n)$
1075 ///
1076 /// $M(n) = O(n (\log n)^2)$
1077 ///
1078 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
1079 ///
1080 /// # Panics
1081 /// Panics if `base` is less than 2.
1082 ///
1083 /// # Examples
1084 /// ```
1085 /// use malachite_base::num::arithmetic::traits::LogBase;
1086 /// use malachite_float::Float;
1087 ///
1088 /// assert_eq!((&Float::from(1000)).log_base(10).to_string(), "3.000");
1089 /// ```
1090 #[inline]
1091 fn log_base(self, base: u64) -> Float {
1092 self.log_base_prec_round_ref(base, self.significant_bits(), Nearest)
1093 .0
1094 }
1095}
1096
1097impl LogBaseAssign<u64> for Float {
1098 /// Replaces a [`Float`] $x$ with $\log_b x$, where $b$ is a `u64` greater than 1, rounding the
1099 /// result to the nearest value of the input's precision.
1100 ///
1101 /// The base-$b$ logarithm of any nonzero negative number is `NaN`. See
1102 /// [`Float::log_base_prec_round`] for the special cases.
1103 ///
1104 /// # Worst-case complexity
1105 /// $T(n) = O(n (\log n)^2 \log\log n)$
1106 ///
1107 /// $M(n) = O(n (\log n)^2)$
1108 ///
1109 /// where $T$ is time, $M$ is additional memory, and $n$ is the precision of the input.
1110 ///
1111 /// # Panics
1112 /// Panics if `base` is less than 2.
1113 ///
1114 /// # Examples
1115 /// ```
1116 /// use malachite_base::num::arithmetic::traits::LogBaseAssign;
1117 /// use malachite_float::Float;
1118 ///
1119 /// let mut x = Float::from(1000);
1120 /// x.log_base_assign(10);
1121 /// assert_eq!(x.to_string(), "3.000");
1122 /// ```
1123 #[inline]
1124 fn log_base_assign(&mut self, base: u64) {
1125 let prec = self.significant_bits();
1126 self.log_base_prec_round_assign(base, prec, Nearest);
1127 }
1128}
1129
1130/// Computes $\log_b x$, the base-$b$ logarithm of a primitive float, where $b$ is a `u64` greater
1131/// than 1. Using this function is more accurate than computing the logarithm using the standard
1132/// library, whose `log` is not always correctly rounded.
1133///
1134/// The base-$b$ logarithm of any negative number is `NaN`.
1135///
1136/// $$
1137/// f(x,b) = \log_b x+\varepsilon.
1138/// $$
1139/// - If $\log_b x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1140/// - If $\log_b x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_b
1141/// x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
1142/// if `T` is a [`f64`], but less if the output is subnormal).
1143///
1144/// Special cases:
1145/// - $f(\text{NaN},b)=\text{NaN}$
1146/// - $f(\infty,b)=\infty$
1147/// - $f(-\infty,b)=\text{NaN}$
1148/// - $f(\pm0.0,b)=-\infty$
1149/// - $f(1.0,b)=0.0$
1150/// - $f(x,b)=\text{NaN}$ for $x<0$
1151///
1152/// Neither overflow nor underflow is possible.
1153///
1154/// # Worst-case complexity
1155/// Constant time and additional memory.
1156///
1157/// # Panics
1158/// Panics if `base` is less than 2.
1159///
1160/// # Examples
1161/// ```
1162/// use malachite_base::num::basic::traits::NegativeInfinity;
1163/// use malachite_base::num::float::NiceFloat;
1164/// use malachite_float::float::arithmetic::log_base::primitive_float_log_base;
1165///
1166/// assert!(primitive_float_log_base(f32::NAN, 10).is_nan());
1167/// assert_eq!(
1168/// NiceFloat(primitive_float_log_base(f32::INFINITY, 10)),
1169/// NiceFloat(f32::INFINITY)
1170/// );
1171/// assert_eq!(
1172/// NiceFloat(primitive_float_log_base(0.0f32, 10)),
1173/// NiceFloat(f32::NEGATIVE_INFINITY)
1174/// );
1175/// // log_10(1000) = 3
1176/// assert_eq!(
1177/// NiceFloat(primitive_float_log_base(1000.0f32, 10)),
1178/// NiceFloat(3.0)
1179/// );
1180/// // log_3(9) = 2
1181/// assert_eq!(
1182/// NiceFloat(primitive_float_log_base(9.0f32, 3)),
1183/// NiceFloat(2.0)
1184/// );
1185/// // log_10(50)
1186/// assert_eq!(
1187/// NiceFloat(primitive_float_log_base(50.0f32, 10)),
1188/// NiceFloat(1.69897)
1189/// );
1190/// assert!(primitive_float_log_base(-1.0f32, 10).is_nan());
1191/// ```
1192#[inline]
1193#[allow(clippy::type_repetition_in_bounds)]
1194pub fn primitive_float_log_base<T: PrimitiveFloat>(x: T, base: u64) -> T
1195where
1196 Float: From<T> + PartialOrd<T>,
1197 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1198{
1199 emulate_float_to_float_fn(|x, prec| Float::log_base_prec(x, base, prec), x)
1200}
1201
1202/// Computes $\log_b x$, the base-$b$ logarithm of a [`Rational`], where $b$ is a `u64` greater than
1203/// 1, returning a primitive float result.
1204///
1205/// If the logarithm is equidistant from two primitive floats, the primitive float with fewer 1s in
1206/// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
1207/// mode.
1208///
1209/// The base-$b$ logarithm of any negative number is `NaN`.
1210///
1211/// $$
1212/// f(x,b) = \log_b x+\varepsilon.
1213/// $$
1214/// - If $\log_b x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1215/// - If $\log_b x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_b
1216/// x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
1217/// if `T` is a [`f64`], but less if the output is subnormal).
1218///
1219/// Special cases:
1220/// - $f(0,b)=-\infty$
1221/// - $f(x,b)=\text{NaN}$ for $x<0$
1222/// - $f(1,b)=0.0$
1223///
1224/// Neither overflow nor underflow is possible.
1225///
1226/// # Worst-case complexity
1227/// Constant time and additional memory.
1228///
1229/// # Panics
1230/// Panics if `base` is less than 2.
1231///
1232/// # Examples
1233/// ```
1234/// use malachite_base::num::basic::traits::{NegativeInfinity, Zero};
1235/// use malachite_base::num::float::NiceFloat;
1236/// use malachite_float::float::arithmetic::log_base::primitive_float_log_base_rational;
1237/// use malachite_q::Rational;
1238///
1239/// assert_eq!(
1240/// NiceFloat(primitive_float_log_base_rational::<f64>(
1241/// &Rational::ZERO,
1242/// 10
1243/// )),
1244/// NiceFloat(f64::NEGATIVE_INFINITY)
1245/// );
1246/// // log_10(1000) = 3
1247/// assert_eq!(
1248/// NiceFloat(primitive_float_log_base_rational::<f64>(
1249/// &Rational::from(1000),
1250/// 10
1251/// )),
1252/// NiceFloat(3.0)
1253/// );
1254/// // log_3(1/9) = -2
1255/// assert_eq!(
1256/// NiceFloat(primitive_float_log_base_rational::<f64>(
1257/// &Rational::from_unsigneds(1u8, 9),
1258/// 3
1259/// )),
1260/// NiceFloat(-2.0)
1261/// );
1262/// // log_10(1/3)
1263/// assert_eq!(
1264/// NiceFloat(primitive_float_log_base_rational::<f64>(
1265/// &Rational::from_unsigneds(1u8, 3),
1266/// 10
1267/// )),
1268/// NiceFloat(-0.47712125471966244)
1269/// );
1270/// assert_eq!(
1271/// NiceFloat(primitive_float_log_base_rational::<f64>(
1272/// &Rational::from(-1000),
1273/// 10
1274/// )),
1275/// NiceFloat(f64::NAN)
1276/// );
1277/// ```
1278#[inline]
1279#[allow(clippy::type_repetition_in_bounds)]
1280pub fn primitive_float_log_base_rational<T: PrimitiveFloat>(x: &Rational, base: u64) -> T
1281where
1282 Float: PartialOrd<T>,
1283 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1284{
1285 emulate_rational_to_float_fn(
1286 |x, prec| Float::log_base_rational_prec_ref(x, base, prec),
1287 x,
1288 )
1289}