malachite_float/float/arithmetic/log_base_2.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, ln_1_plus_rational_brackets, sliver_of_one};
17use crate::float::arithmetic::round_near_x::float_round_near_x;
18use crate::float::basic::extended::ExtendedFloat;
19use crate::{
20 ComparableFloatRef, Float, emulate_float_to_float_fn, emulate_rational_to_float_fn,
21 float_either_zero, float_infinity, float_nan, float_negative_infinity, floor_and_ceiling,
22};
23use core::cmp::Ordering::{self, *};
24use malachite_base::num::arithmetic::traits::{
25 CeilingLogBase2, CheckedLogBase2, IsPowerOf2, LogBase2, LogBase2Assign, PowerOf2, Sign,
26};
27use malachite_base::num::basic::floats::PrimitiveFloat;
28use malachite_base::num::basic::integers::PrimitiveInt;
29use malachite_base::num::basic::traits::{One, 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::arithmetic::float::round::float_can_round;
34use malachite_nz::platform::Limb;
35use malachite_q::Rational;
36
37// The computation of log_base_2(x) is done by log_base_2(x) = ln(x) / ln(2).
38//
39// This is mpfr_log2 from log2.c, MPFR 4.3.0, where the input is finite, nonzero, and positive.
40fn log_base_2_prec_round_normal(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
41 // If x is 1, the result is 0.
42 if *x == 1u32 {
43 return (Float::ZERO, Equal);
44 }
45 // If x is 2^k, log_base_2(x) is exact (though possibly subject to rounding at the target
46 // precision).
47 if x.is_power_of_2() {
48 return Float::from_signed_prec_round(i64::from(x.get_exponent().unwrap()) - 1, prec, rm);
49 }
50 // log_2(x) for x in a sliver of 1 can fall below the smallest positive Float; the 1-plus-x form
51 // handles that underflow region.
52 match sliver_of_one(x) {
53 SliverOfOne::Representable(d) => return d.log_base_2_1_plus_x_prec_round(prec, rm),
54 SliverOfOne::Underflow => {
55 return Float::log_base_2_rational_prec_round(Rational::exact_from(x), prec, rm);
56 }
57 SliverOfOne::No => {}
58 }
59 // The result is never exactly representable for other inputs.
60 assert_ne!(rm, Exact, "Inexact log_base_2");
61 // Compute the precision of the intermediary variable: the optimal number of bits, see
62 // algorithms.tex.
63 let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
64 let mut increment = Limb::WIDTH;
65 loop {
66 // ln(x) / ln(2)
67 let t = x
68 .ln_prec_ref(working_prec)
69 .0
70 .div_prec(Float::ln_2_prec(working_prec).0, working_prec)
71 .0;
72 // Estimation of the error.
73 if float_can_round(t.significand_ref().unwrap(), working_prec - 3, prec, rm) {
74 return Float::from_float_prec_round(t, prec, rm);
75 }
76 // Increase the precision.
77 working_prec += increment;
78 increment = working_prec >> 1;
79 }
80}
81
82// Computes `log_2(1 + eps)` for a small nonzero [`Rational`] `eps` (`x - 1`, where `x` is near 1).
83// The result is near zero, so unlike the near-a-larger-power case it must be computed directly
84// rather than rounded near an integer; a Ziv loop over a [`Float`] approximation of `eps` does so
85// without the catastrophic cancellation that `ln(x)` would suffer for `x` near 1. Brackets of
86// log2(x') for an exact positive Rational x', as exact Rationals, to a relative accuracy of about
87// 2^-wprec. (`rational_pow` centers x' in [1/sqrt(2), sqrt(2)) -- the mantissa is taken to the
88// nearest power of 2, so x' is never near 2 -- while `unsigned_pow_rational` passes an integer x'
89// >= 3.) x' comfortably away from 1 goes through directed Float logs; x' within a sliver of 1 --
90// from either side, where a Float log would lose all precision to the exponent range -- goes
91// through the exact atanh-series brackets divided by ln(2) brackets.
92pub(crate) fn log_2_rational_brackets(x: &Rational, wprec: u64) -> (Rational, Rational) {
93 let e = x - Rational::ONE;
94 if e == 0u32 {
95 return (Rational::ZERO, Rational::ZERO);
96 }
97 if e.floor_log_base_2_abs() >= -8 {
98 // Directed Float computation: round x' outward, then take directed logs. x' is bounded away
99 // from both 1 and 2, so neither log collapses to an exact power-of-2 boundary.
100 (
101 Rational::exact_from(
102 &Float::from_rational_prec_round_ref(x, wprec, Floor)
103 .0
104 .log_base_2_round(Floor)
105 .0,
106 ),
107 Rational::exact_from(
108 &Float::from_rational_prec_round_ref(x, wprec, Ceiling)
109 .0
110 .log_base_2_round(Ceiling)
111 .0,
112 ),
113 )
114 } else {
115 // ln(x') as exact Rational brackets, then divide by ln(2) brackets, rounding outward. The
116 // ln brackets share the sign of e = x' - 1; the outward division depends on that sign.
117 let (ln_lo, ln_hi) = ln_1_plus_rational_brackets(&e, wprec);
118 let (ln_2_lo, ln_2_hi) = floor_and_ceiling(Float::ln_2_prec_round(wprec, Floor));
119 let ln_2_lo = Rational::exact_from(&ln_2_lo);
120 let ln_2_hi = Rational::exact_from(&ln_2_hi);
121 if e > 0u32 {
122 (ln_lo / ln_2_hi, ln_hi / ln_2_lo)
123 } else {
124 (ln_lo / ln_2_lo, ln_hi / ln_2_hi)
125 }
126 }
127}
128
129// Computes log2(1 + eps) for an exact Rational eps with 1 + eps in [1/sqrt(2), sqrt(2)) (so eps in
130// [1/sqrt(2) - 1, sqrt(2) - 1)). Brackets log2(1 + eps) between exact Rationals and rounds each end
131// via `from_rational_prec_round`, which handles the underflow region correctly -- so a sub-`MIN`
132// eps (whose log2 falls below the smallest positive Float) rounds correctly instead of flushing a
133// Float approximation of eps to zero.
134fn log_base_2_rational_near_one(eps: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
135 let x = Rational::ONE + eps;
136 let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
137 let mut increment = Limb::WIDTH;
138 loop {
139 let (lo, hi) = log_2_rational_brackets(&x, working_prec);
140 let (f_lo, mut o_lo) = Float::from_rational_prec_round_ref(&lo, prec, rm);
141 let (f_hi, mut o_hi) = Float::from_rational_prec_round_ref(&hi, prec, rm);
142 if o_lo == Equal {
143 o_lo = o_hi;
144 }
145 if o_hi == Equal {
146 o_hi = o_lo;
147 }
148 if o_lo == o_hi && ComparableFloatRef(&f_lo) == ComparableFloatRef(&f_hi) {
149 return (f_lo, o_lo);
150 }
151 working_prec += increment;
152 increment = working_prec >> 1;
153 }
154}
155
156// If `x` is close enough to a power of 2 that the general Ziv loop would need a precision
157// proportional to the distance (potentially exhausting memory), returns the correctly-rounded
158// `log_2(x)`; otherwise returns `None`. `x` must be positive and not a power of 2.
159//
160// `log_2(x) = k + log_2(x / 2^k)` for the nearest power of 2, `2^k`. When `x` is very close to
161// `2^k` the offset `log_2(x / 2^k)` is tiny: for `k != 0` the result is `k` nudged by a fraction of
162// an ulp, which `float_round_near_x` rounds directly (returning `None` when the offset is not
163// sub-ulp, so the general loop — which then converges quickly — takes over); for `k == 0` (`x`
164// near 1) the result is the tiny offset itself.
165fn log_base_2_rational_near_power_of_2(
166 x: &Rational,
167 prec: u64,
168 rm: RoundingMode,
169) -> Option<(Float, Ordering)> {
170 // 2^m <= x < 2^(m + 1)
171 let m = x.floor_log_base_2_abs();
172 let pow_lo = Rational::power_of_2(m);
173 let pow_hi = &pow_lo << 1u32;
174 // eps = x / 2^k - 1 for the nearer of the two surrounding powers of 2, 2^k.
175 let dist_lo = x - &pow_lo;
176 let dist_hi = &pow_hi - x;
177 let (k, eps) = if dist_lo <= dist_hi {
178 (m, dist_lo / pow_lo)
179 } else {
180 (m + 1, -(dist_hi / pow_hi))
181 };
182 if k == 0 {
183 // x is near 1, so log_2(x) = log_2(1 + eps) is near zero.
184 return Some(log_base_2_rational_near_one(&eps, prec, rm));
185 }
186 // eps is nonzero since x is not a power of 2.
187 let eps_exp = eps.floor_log_base_2_abs();
188 let k_float = Float::from(k);
189 let exp_k = i64::from(k_float.get_exponent().unwrap());
190 // |log_2(1 + eps)| < 3|eps| < 2^(eps_exp + 3), so passing err = exp_k - eps_exp - 3 to
191 // `float_round_near_x` (which requires |offset| < 2^(exp_k - err)) is sound.
192 let err = exp_k - eps_exp - 3;
193 if err <= 0 {
194 return None;
195 }
196 // The offset moves the magnitude up (away from zero) iff it has the same sign as k.
197 let dir = (eps > 0u32) == (k > 0);
198 float_round_near_x(&k_float, u64::exact_from(err), dir, prec, rm)
199}
200
201// The computation of log_base_2(x) is done by log_base_2(x) = ln(x) / ln(2). `ln_rational_prec`
202// handles inputs whose magnitudes are outside the representable range of `Float`; the result of the
203// division has greater magnitude than the result of `ln_rational_prec`, but only by a factor of
204// 1/ln(2), so the division cannot overflow or underflow if the `ln` didn't.
205fn log_base_2_rational_prec_round_helper(
206 x: &Rational,
207 prec: u64,
208 rm: RoundingMode,
209) -> (Float, Ordering) {
210 // When x is extremely close to a power of 2, log_2(x) is extremely close to an integer, and the
211 // Ziv loop below would need a precision proportional to the distance to round it. Handle that
212 // case separately.
213 if let Some(result) = log_base_2_rational_near_power_of_2(x, prec, rm) {
214 return result;
215 }
216 let mut working_prec = prec + 3 + prec.ceiling_log_base_2();
217 let mut increment = Limb::WIDTH;
218 loop {
219 // ln(x) / ln(2)
220 let t = Float::ln_rational_prec_ref(x, working_prec)
221 .0
222 .div_prec(Float::ln_2_prec(working_prec).0, working_prec)
223 .0;
224 // Estimation of the error.
225 if float_can_round(t.significand_ref().unwrap(), working_prec - 3, prec, rm) {
226 return Float::from_float_prec_round(t, prec, rm);
227 }
228 // Increase the precision.
229 working_prec += increment;
230 increment = working_prec >> 1;
231 }
232}
233
234// Computes `log_2(r)` as an `ExtendedFloat`, accurate to within 2 ulps of `prec` bits. `r` must be
235// positive and not equal to 1.
236//
237// The result is kept in the extended exponent range so that an `r` extremely close to 1 -- where
238// `log_2(r)` is tiny and would underflow an ordinary `Float` (its value-exponent reaches `-2^63`,
239// far below `MIN_EXPONENT = -(2^30 - 1)`) -- is represented faithfully rather than flushed to zero.
240// This lets the logarithm-with-a-rational-base functions divide two such logs and clamp only once,
241// at the very end, rather than losing the operand entirely.
242//
243// For `r` not pathologically near 1, the ordinary `log_2(r)` is a normal `Float`, correctly rounded
244// (at most 1/2 ulp), and is simply wrapped. When `r` is within about `2^(-2^30)` of 1, `log_2(r) =
245// log_2(1 + y)` with `y = r - 1`, and `log_2(1 + y) = y / ln 2 + O(y^2)`; here `|y| < 2^(-2^30)` is
246// far smaller than `2^(-prec)`, so the `O(y^2)` term is below an ulp and `y / ln 2` (computed in
247// the extended range, where `y`'s exponent fits in the `i64`) is accurate to within 2 ulps (1/2
248// from the conversion of `y`, 1/2 from the division, the rest from the dropped term).
249pub(crate) fn extended_log_base_2_of_rational(r: &Rational, prec: u64) -> ExtendedFloat {
250 // `log_2(r)` underflows an ordinary `Float` only when `r` is within roughly `2^(-2^30)` of 1.
251 // Switch to the linear approximation a couple of exponents before that boundary; the ordinary
252 // path is then guaranteed not to underflow, and the linear path is valid well beyond it.
253 let y = r - Rational::ONE;
254 if y.floor_log_base_2_abs() <= Float::MIN_EXPONENT_PLUS_1_I64 {
255 let y_ext = ExtendedFloat::from_rational_prec_round(y, prec, Nearest).0;
256 let ln_2 = ExtendedFloat::from(Float::ln_2_prec(prec).0);
257 y_ext.div_prec_val_ref(&ln_2, prec).0
258 } else {
259 ExtendedFloat::from(Float::log_base_2_rational_prec_ref(r, prec).0)
260 }
261}
262
263impl Float {
264 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result to the specified
265 /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
266 /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
267 /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
268 /// whenever this function returns a `NaN` it also returns `Equal`.
269 ///
270 /// The base-2 logarithm of any nonzero negative number is `NaN`.
271 ///
272 /// See [`RoundingMode`] for a description of the possible rounding modes.
273 ///
274 /// $$
275 /// f(x,p,m) = \log_2 x+\varepsilon.
276 /// $$
277 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
278 /// 0.
279 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
280 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$.
281 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
282 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$.
283 ///
284 /// If the output has a precision, it is `prec`.
285 ///
286 /// Special cases:
287 /// - $f(\text{NaN},p,m)=\text{NaN}$
288 /// - $f(\infty,p,m)=\infty$
289 /// - $f(-\infty,p,m)=\text{NaN}$
290 /// - $f(\pm0.0,p,m)=-\infty$
291 /// - $f(1.0,p,m)=0.0$, and the result is exact
292 /// - $f(2^k,p,m)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
293 /// representable with precision $p$
294 /// - $f(x,p,m)=\text{NaN}$ for $x<0$
295 ///
296 /// Neither overflow nor underflow is possible.
297 ///
298 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_2_prec`] instead. If
299 /// you know that your target precision is the precision of the input, consider using
300 /// [`Float::log_base_2_round`] instead. If both of these things are true, consider using
301 /// [`Float::log_base_2`] instead.
302 ///
303 /// # Worst-case complexity
304 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
305 ///
306 /// $M(n, m) = O(n \log n + m)$
307 ///
308 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
309 /// `self.significant_bits()`.
310 ///
311 /// # Panics
312 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
313 /// with the given precision. (The result is exactly representable if and only if the input is
314 /// `NaN`, infinite, zero, equal to 1, or a power of 2 whose base-2 logarithm is representable
315 /// with the given precision.)
316 ///
317 /// # Examples
318 /// ```
319 /// use malachite_base::rounding_modes::RoundingMode::*;
320 /// use malachite_float::Float;
321 /// use std::cmp::Ordering::*;
322 ///
323 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
324 /// .0
325 /// .log_base_2_prec_round(5, Floor);
326 /// assert_eq!(log.to_string(), "3.25");
327 /// assert_eq!(o, Less);
328 ///
329 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
330 /// .0
331 /// .log_base_2_prec_round(5, Ceiling);
332 /// assert_eq!(log.to_string(), "3.38");
333 /// assert_eq!(o, Greater);
334 ///
335 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
336 /// .0
337 /// .log_base_2_prec_round(5, Nearest);
338 /// assert_eq!(log.to_string(), "3.38");
339 /// assert_eq!(o, Greater);
340 ///
341 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
342 /// .0
343 /// .log_base_2_prec_round(20, Floor);
344 /// assert_eq!(log.to_string(), "3.3219261");
345 /// assert_eq!(o, Less);
346 ///
347 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
348 /// .0
349 /// .log_base_2_prec_round(20, Ceiling);
350 /// assert_eq!(log.to_string(), "3.3219299");
351 /// assert_eq!(o, Greater);
352 ///
353 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
354 /// .0
355 /// .log_base_2_prec_round(20, Nearest);
356 /// assert_eq!(log.to_string(), "3.3219299");
357 /// assert_eq!(o, Greater);
358 /// ```
359 #[inline]
360 pub fn log_base_2_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
361 assert_ne!(prec, 0);
362 match self {
363 Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
364 (float_nan!(), Equal)
365 }
366 float_either_zero!() => (float_negative_infinity!(), Equal),
367 float_infinity!() => (float_infinity!(), Equal),
368 _ => log_base_2_prec_round_normal(&self, prec, rm),
369 }
370 }
371
372 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result to the specified
373 /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
374 /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
375 /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
376 /// whenever this function returns a `NaN` it also returns `Equal`.
377 ///
378 /// The base-2 logarithm of any nonzero negative number is `NaN`.
379 ///
380 /// See [`RoundingMode`] for a description of the possible rounding modes.
381 ///
382 /// $$
383 /// f(x,p,m) = \log_2 x+\varepsilon.
384 /// $$
385 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
386 /// 0.
387 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
388 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$.
389 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
390 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$.
391 ///
392 /// If the output has a precision, it is `prec`.
393 ///
394 /// Special cases:
395 /// - $f(\text{NaN},p,m)=\text{NaN}$
396 /// - $f(\infty,p,m)=\infty$
397 /// - $f(-\infty,p,m)=\text{NaN}$
398 /// - $f(\pm0.0,p,m)=-\infty$
399 /// - $f(1.0,p,m)=0.0$, and the result is exact
400 /// - $f(2^k,p,m)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
401 /// representable with precision $p$
402 /// - $f(x,p,m)=\text{NaN}$ for $x<0$
403 ///
404 /// Neither overflow nor underflow is possible.
405 ///
406 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_2_prec_ref`]
407 /// instead. If you know that your target precision is the precision of the input, consider
408 /// using [`Float::log_base_2_round_ref`] instead. If both of these things are true, consider
409 /// using `(&Float).log_base_2()` instead.
410 ///
411 /// # Worst-case complexity
412 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
413 ///
414 /// $M(n, m) = O(n \log n + m)$
415 ///
416 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
417 /// `self.significant_bits()`.
418 ///
419 /// # Panics
420 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
421 /// with the given precision. (The result is exactly representable if and only if the input is
422 /// `NaN`, infinite, zero, equal to 1, or a power of 2 whose base-2 logarithm is representable
423 /// with the given precision.)
424 ///
425 /// # Examples
426 /// ```
427 /// use malachite_base::rounding_modes::RoundingMode::*;
428 /// use malachite_float::Float;
429 /// use std::cmp::Ordering::*;
430 ///
431 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
432 /// .0
433 /// .log_base_2_prec_round_ref(5, Floor);
434 /// assert_eq!(log.to_string(), "3.25");
435 /// assert_eq!(o, Less);
436 ///
437 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
438 /// .0
439 /// .log_base_2_prec_round_ref(5, Ceiling);
440 /// assert_eq!(log.to_string(), "3.38");
441 /// assert_eq!(o, Greater);
442 ///
443 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
444 /// .0
445 /// .log_base_2_prec_round_ref(5, Nearest);
446 /// assert_eq!(log.to_string(), "3.38");
447 /// assert_eq!(o, Greater);
448 ///
449 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
450 /// .0
451 /// .log_base_2_prec_round_ref(20, Floor);
452 /// assert_eq!(log.to_string(), "3.3219261");
453 /// assert_eq!(o, Less);
454 ///
455 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
456 /// .0
457 /// .log_base_2_prec_round_ref(20, Ceiling);
458 /// assert_eq!(log.to_string(), "3.3219299");
459 /// assert_eq!(o, Greater);
460 ///
461 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
462 /// .0
463 /// .log_base_2_prec_round_ref(20, Nearest);
464 /// assert_eq!(log.to_string(), "3.3219299");
465 /// assert_eq!(o, Greater);
466 /// ```
467 #[inline]
468 pub fn log_base_2_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
469 assert_ne!(prec, 0);
470 match self {
471 Self(NaN | Infinity { sign: false } | Finite { sign: false, .. }) => {
472 (float_nan!(), Equal)
473 }
474 float_either_zero!() => (float_negative_infinity!(), Equal),
475 float_infinity!() => (float_infinity!(), Equal),
476 _ => log_base_2_prec_round_normal(self, prec, rm),
477 }
478 }
479
480 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result to the nearest value of
481 /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
482 /// indicating whether the rounded value is less than, equal to, or greater than the exact
483 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
484 /// `NaN` it also returns `Equal`.
485 ///
486 /// The base-2 logarithm of any nonzero negative number is `NaN`.
487 ///
488 /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
489 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
490 /// description of the `Nearest` rounding mode.
491 ///
492 /// $$
493 /// f(x,p) = \log_2 x+\varepsilon.
494 /// $$
495 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
496 /// 0.
497 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
498 /// x|\rfloor-p}$.
499 ///
500 /// If the output has a precision, it is `prec`.
501 ///
502 /// Special cases:
503 /// - $f(\text{NaN},p)=\text{NaN}$
504 /// - $f(\infty,p)=\infty$
505 /// - $f(-\infty,p)=\text{NaN}$
506 /// - $f(\pm0.0,p)=-\infty$
507 /// - $f(1.0,p)=0.0$, and the result is exact
508 /// - $f(2^k,p)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
509 /// representable with precision $p$
510 /// - $f(x,p)=\text{NaN}$ for $x<0$
511 ///
512 /// Neither overflow nor underflow is possible.
513 ///
514 /// If you want to use a rounding mode other than `Nearest`, consider using
515 /// [`Float::log_base_2_prec_round`] instead. If you know that your target precision is the
516 /// precision of the input, consider using [`Float::log_base_2`] instead.
517 ///
518 /// # Worst-case complexity
519 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
520 ///
521 /// $M(n, m) = O(n \log n + m)$
522 ///
523 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
524 /// `self.significant_bits()`.
525 ///
526 /// # Panics
527 /// Panics if `prec` is zero.
528 ///
529 /// # Examples
530 /// ```
531 /// use malachite_float::Float;
532 /// use std::cmp::Ordering::*;
533 ///
534 /// let (log, o) = Float::from_unsigned_prec(10u32, 100).0.log_base_2_prec(5);
535 /// assert_eq!(log.to_string(), "3.38");
536 /// assert_eq!(o, Greater);
537 ///
538 /// let (log, o) = Float::from_unsigned_prec(10u32, 100).0.log_base_2_prec(20);
539 /// assert_eq!(log.to_string(), "3.3219299");
540 /// assert_eq!(o, Greater);
541 /// ```
542 #[inline]
543 pub fn log_base_2_prec(self, prec: u64) -> (Self, Ordering) {
544 self.log_base_2_prec_round(prec, Nearest)
545 }
546
547 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result to the nearest value of
548 /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
549 /// returned, indicating whether the rounded value is less than, equal to, or greater than the
550 /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
551 /// returns a `NaN` it also returns `Equal`.
552 ///
553 /// The base-2 logarithm of any nonzero negative number is `NaN`.
554 ///
555 /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
556 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
557 /// description of the `Nearest` rounding mode.
558 ///
559 /// $$
560 /// f(x,p) = \log_2 x+\varepsilon.
561 /// $$
562 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
563 /// 0.
564 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
565 /// x|\rfloor-p}$.
566 ///
567 /// If the output has a precision, it is `prec`.
568 ///
569 /// Special cases:
570 /// - $f(\text{NaN},p)=\text{NaN}$
571 /// - $f(\infty,p)=\infty$
572 /// - $f(-\infty,p)=\text{NaN}$
573 /// - $f(\pm0.0,p)=-\infty$
574 /// - $f(1.0,p)=0.0$, and the result is exact
575 /// - $f(2^k,p)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
576 /// representable with precision $p$
577 /// - $f(x,p)=\text{NaN}$ for $x<0$
578 ///
579 /// Neither overflow nor underflow is possible.
580 ///
581 /// If you want to use a rounding mode other than `Nearest`, consider using
582 /// [`Float::log_base_2_prec_round_ref`] instead. If you know that your target precision is the
583 /// precision of the input, consider using `(&Float).log_base_2()` instead.
584 ///
585 /// # Worst-case complexity
586 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
587 ///
588 /// $M(n, m) = O(n \log n + m)$
589 ///
590 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
591 /// `self.significant_bits()`.
592 ///
593 /// # Panics
594 /// Panics if `prec` is zero.
595 ///
596 /// # Examples
597 /// ```
598 /// use malachite_float::Float;
599 /// use std::cmp::Ordering::*;
600 ///
601 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
602 /// .0
603 /// .log_base_2_prec_ref(5);
604 /// assert_eq!(log.to_string(), "3.38");
605 /// assert_eq!(o, Greater);
606 ///
607 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
608 /// .0
609 /// .log_base_2_prec_ref(20);
610 /// assert_eq!(log.to_string(), "3.3219299");
611 /// assert_eq!(o, Greater);
612 /// ```
613 #[inline]
614 pub fn log_base_2_prec_ref(&self, prec: u64) -> (Self, Ordering) {
615 self.log_base_2_prec_round_ref(prec, Nearest)
616 }
617
618 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result with the specified
619 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
620 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
621 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
622 /// returns `Equal`.
623 ///
624 /// The base-2 logarithm of any nonzero negative number is `NaN`.
625 ///
626 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
627 /// description of the possible rounding modes.
628 ///
629 /// $$
630 /// f(x,m) = \log_2 x+\varepsilon.
631 /// $$
632 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
633 /// 0.
634 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
635 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$, where $p$ is the precision of the input.
636 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
637 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$, where $p$ is the precision of the input.
638 ///
639 /// If the output has a precision, it is the precision of the input.
640 ///
641 /// Special cases:
642 /// - $f(\text{NaN},m)=\text{NaN}$
643 /// - $f(\infty,m)=\infty$
644 /// - $f(-\infty,m)=\text{NaN}$
645 /// - $f(\pm0.0,m)=-\infty$
646 /// - $f(1.0,m)=0.0$, and the result is exact
647 /// - $f(2^k,m)=k$, rounded to the precision of the input; the result is exact if and only if
648 /// $k$ is representable with that precision
649 /// - $f(x,m)=\text{NaN}$ for $x<0$
650 ///
651 /// Neither overflow nor underflow is possible.
652 ///
653 /// If you want to specify an output precision, consider using [`Float::log_base_2_prec_round`]
654 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
655 /// [`Float::log_base_2`] instead.
656 ///
657 /// # Worst-case complexity
658 /// $T(n) = O(n (\log n)^2 \log\log n)$
659 ///
660 /// $M(n) = O(n \log n)$
661 ///
662 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
663 ///
664 /// # Panics
665 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
666 /// precision. (The result is exactly representable if and only if the input is `NaN`, infinite,
667 /// zero, equal to 1, or a power of 2 whose base-2 logarithm is representable with the input
668 /// precision.)
669 ///
670 /// # Examples
671 /// ```
672 /// use malachite_base::rounding_modes::RoundingMode::*;
673 /// use malachite_float::Float;
674 /// use std::cmp::Ordering::*;
675 ///
676 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
677 /// .0
678 /// .log_base_2_round(Floor);
679 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294867");
680 /// assert_eq!(o, Less);
681 ///
682 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
683 /// .0
684 /// .log_base_2_round(Ceiling);
685 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294898");
686 /// assert_eq!(o, Greater);
687 ///
688 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
689 /// .0
690 /// .log_base_2_round(Nearest);
691 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294898");
692 /// assert_eq!(o, Greater);
693 /// ```
694 #[inline]
695 pub fn log_base_2_round(self, rm: RoundingMode) -> (Self, Ordering) {
696 let prec = self.significant_bits();
697 self.log_base_2_prec_round(prec, rm)
698 }
699
700 /// Computes $\log_2 x$, where $x$ is a [`Float`], rounding the result with the specified
701 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
702 /// indicating whether the rounded value is less than, equal to, or greater than the exact
703 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
704 /// `NaN` it also returns `Equal`.
705 ///
706 /// The base-2 logarithm of any nonzero negative number is `NaN`.
707 ///
708 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
709 /// description of the possible rounding modes.
710 ///
711 /// $$
712 /// f(x,m) = \log_2 x+\varepsilon.
713 /// $$
714 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
715 /// 0.
716 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
717 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$, where $p$ is the precision of the input.
718 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
719 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$, where $p$ is the precision of the input.
720 ///
721 /// If the output has a precision, it is the precision of the input.
722 ///
723 /// Special cases:
724 /// - $f(\text{NaN},m)=\text{NaN}$
725 /// - $f(\infty,m)=\infty$
726 /// - $f(-\infty,m)=\text{NaN}$
727 /// - $f(\pm0.0,m)=-\infty$
728 /// - $f(1.0,m)=0.0$, and the result is exact
729 /// - $f(2^k,m)=k$, rounded to the precision of the input; the result is exact if and only if
730 /// $k$ is representable with that precision
731 /// - $f(x,m)=\text{NaN}$ for $x<0$
732 ///
733 /// Neither overflow nor underflow is possible.
734 ///
735 /// If you want to specify an output precision, consider using
736 /// [`Float::log_base_2_prec_round_ref`] instead. If you know you'll be using the `Nearest`
737 /// rounding mode, consider using `(&Float).log_base_2()` instead.
738 ///
739 /// # Worst-case complexity
740 /// $T(n) = O(n (\log n)^2 \log\log n)$
741 ///
742 /// $M(n) = O(n \log n)$
743 ///
744 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
745 ///
746 /// # Panics
747 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
748 /// precision. (The result is exactly representable if and only if the input is `NaN`, infinite,
749 /// zero, equal to 1, or a power of 2 whose base-2 logarithm is representable with the input
750 /// precision.)
751 ///
752 /// # Examples
753 /// ```
754 /// use malachite_base::rounding_modes::RoundingMode::*;
755 /// use malachite_float::Float;
756 /// use std::cmp::Ordering::*;
757 ///
758 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
759 /// .0
760 /// .log_base_2_round_ref(Floor);
761 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294867");
762 /// assert_eq!(o, Less);
763 ///
764 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
765 /// .0
766 /// .log_base_2_round_ref(Ceiling);
767 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294898");
768 /// assert_eq!(o, Greater);
769 ///
770 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
771 /// .0
772 /// .log_base_2_round_ref(Nearest);
773 /// assert_eq!(log.to_string(), "3.3219280948873623478703194294898");
774 /// assert_eq!(o, Greater);
775 /// ```
776 #[inline]
777 pub fn log_base_2_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
778 let prec = self.significant_bits();
779 self.log_base_2_prec_round_ref(prec, rm)
780 }
781
782 /// Computes $\log_2 x$, where $x$ is a [`Float`], in place, rounding the result to the
783 /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
784 /// indicating whether the rounded value is less than, equal to, or greater than the exact
785 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
786 /// [`Float`] to `NaN` it also returns `Equal`.
787 ///
788 /// The base-2 logarithm of any nonzero negative number is `NaN`.
789 ///
790 /// See [`RoundingMode`] for a description of the possible rounding modes.
791 ///
792 /// $$
793 /// x \gets \log_2 x+\varepsilon.
794 /// $$
795 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
796 /// 0.
797 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
798 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$.
799 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
800 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$.
801 ///
802 /// If the output has a precision, it is `prec`.
803 ///
804 /// See the [`Float::log_base_2_prec_round`] documentation for information on special cases,
805 /// overflow, and underflow.
806 ///
807 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_2_prec_assign`]
808 /// instead. If you know that your target precision is the precision of the input, consider
809 /// using [`Float::log_base_2_round_assign`] instead. If both of these things are true, consider
810 /// using [`Float::log_base_2_assign`] instead.
811 ///
812 /// # Worst-case complexity
813 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
814 ///
815 /// $M(n, m) = O(n \log n + m)$
816 ///
817 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
818 /// `self.significant_bits()`.
819 ///
820 /// # Panics
821 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
822 /// with the given precision. (The result is exactly representable if and only if the input is
823 /// `NaN`, infinite, zero, equal to 1, or a power of 2 whose base-2 logarithm is representable
824 /// with the given precision.)
825 ///
826 /// # Examples
827 /// ```
828 /// use malachite_base::rounding_modes::RoundingMode::*;
829 /// use malachite_float::Float;
830 /// use std::cmp::Ordering::*;
831 ///
832 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
833 /// assert_eq!(x.log_base_2_prec_round_assign(5, Floor), Less);
834 /// assert_eq!(x.to_string(), "3.25");
835 ///
836 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
837 /// assert_eq!(x.log_base_2_prec_round_assign(5, Ceiling), Greater);
838 /// assert_eq!(x.to_string(), "3.38");
839 ///
840 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
841 /// assert_eq!(x.log_base_2_prec_round_assign(5, Nearest), Greater);
842 /// assert_eq!(x.to_string(), "3.38");
843 ///
844 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
845 /// assert_eq!(x.log_base_2_prec_round_assign(20, Floor), Less);
846 /// assert_eq!(x.to_string(), "3.3219261");
847 ///
848 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
849 /// assert_eq!(x.log_base_2_prec_round_assign(20, Ceiling), Greater);
850 /// assert_eq!(x.to_string(), "3.3219299");
851 ///
852 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
853 /// assert_eq!(x.log_base_2_prec_round_assign(20, Nearest), Greater);
854 /// assert_eq!(x.to_string(), "3.3219299");
855 /// ```
856 #[inline]
857 pub fn log_base_2_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
858 let (result, o) = core::mem::take(self).log_base_2_prec_round(prec, rm);
859 *self = result;
860 o
861 }
862
863 /// Computes $\log_2 x$, where $x$ is a [`Float`], in place, rounding the result to the nearest
864 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
865 /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
866 /// not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
867 /// returns `Equal`.
868 ///
869 /// The base-2 logarithm of any nonzero negative number is `NaN`.
870 ///
871 /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
872 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
873 /// description of the `Nearest` rounding mode.
874 ///
875 /// $$
876 /// x \gets \log_2 x+\varepsilon.
877 /// $$
878 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
879 /// 0.
880 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
881 /// x|\rfloor-p}$.
882 ///
883 /// If the output has a precision, it is `prec`.
884 ///
885 /// See the [`Float::log_base_2_prec`] documentation for information on special cases, overflow,
886 /// and underflow.
887 ///
888 /// If you want to use a rounding mode other than `Nearest`, consider using
889 /// [`Float::log_base_2_prec_round_assign`] instead. If you know that your target precision is
890 /// the precision of the input, consider using [`Float::log_base_2_assign`] instead.
891 ///
892 /// # Worst-case complexity
893 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
894 ///
895 /// $M(n, m) = O(n \log n + m)$
896 ///
897 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
898 /// `self.significant_bits()`.
899 ///
900 /// # Panics
901 /// Panics if `prec` is zero.
902 ///
903 /// # Examples
904 /// ```
905 /// use malachite_float::Float;
906 /// use std::cmp::Ordering::*;
907 ///
908 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
909 /// assert_eq!(x.log_base_2_prec_assign(5), Greater);
910 /// assert_eq!(x.to_string(), "3.38");
911 ///
912 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
913 /// assert_eq!(x.log_base_2_prec_assign(20), Greater);
914 /// assert_eq!(x.to_string(), "3.3219299");
915 /// ```
916 #[inline]
917 pub fn log_base_2_prec_assign(&mut self, prec: u64) -> Ordering {
918 self.log_base_2_prec_round_assign(prec, Nearest)
919 }
920
921 /// Computes $\log_2 x$, where $x$ is a [`Float`], in place, rounding the result with the
922 /// specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded value
923 /// is less than, equal to, or greater than the exact value. Although `NaN`s are not comparable
924 /// to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns
925 /// `Equal`.
926 ///
927 /// The base-2 logarithm of any nonzero negative number is `NaN`.
928 ///
929 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
930 /// description of the possible rounding modes.
931 ///
932 /// $$
933 /// x \gets \log_2 x+\varepsilon.
934 /// $$
935 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
936 /// 0.
937 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
938 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$, where $p$ is the precision of the input.
939 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
940 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$, where $p$ is the precision of the input.
941 ///
942 /// If the output has a precision, it is the precision of the input.
943 ///
944 /// See the [`Float::log_base_2_round`] documentation for information on special cases,
945 /// overflow, and underflow.
946 ///
947 /// If you want to specify an output precision, consider using
948 /// [`Float::log_base_2_prec_round_assign`] instead. If you know you'll be using the `Nearest`
949 /// rounding mode, consider using [`Float::log_base_2_assign`] instead.
950 ///
951 /// # Worst-case complexity
952 /// $T(n) = O(n (\log n)^2 \log\log n)$
953 ///
954 /// $M(n) = O(n \log n)$
955 ///
956 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
957 ///
958 /// # Panics
959 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
960 /// precision. (The result is exactly representable if and only if the input is `NaN`, infinite,
961 /// zero, equal to 1, or a power of 2 whose base-2 logarithm is representable with the input
962 /// precision.)
963 ///
964 /// # Examples
965 /// ```
966 /// use malachite_base::rounding_modes::RoundingMode::*;
967 /// use malachite_float::Float;
968 /// use std::cmp::Ordering::*;
969 ///
970 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
971 /// assert_eq!(x.log_base_2_round_assign(Floor), Less);
972 /// assert_eq!(x.to_string(), "3.3219280948873623478703194294867");
973 ///
974 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
975 /// assert_eq!(x.log_base_2_round_assign(Ceiling), Greater);
976 /// assert_eq!(x.to_string(), "3.3219280948873623478703194294898");
977 ///
978 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
979 /// assert_eq!(x.log_base_2_round_assign(Nearest), Greater);
980 /// assert_eq!(x.to_string(), "3.3219280948873623478703194294898");
981 /// ```
982 #[inline]
983 pub fn log_base_2_round_assign(&mut self, rm: RoundingMode) -> Ordering {
984 let prec = self.significant_bits();
985 self.log_base_2_prec_round_assign(prec, rm)
986 }
987
988 /// Computes $\log_2 x$, where $x$ is a [`Rational`], rounding the result to the specified
989 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
990 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
991 /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
992 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
993 /// `Equal`.
994 ///
995 /// The base-2 logarithm of any negative number is `NaN`.
996 ///
997 /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
998 /// or too small to be representable as [`Float`]s.
999 ///
1000 /// See [`RoundingMode`] for a description of the possible rounding modes.
1001 ///
1002 /// $$
1003 /// f(x,p,m) = \log_2 x+\varepsilon.
1004 /// $$
1005 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1006 /// 0.
1007 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1008 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$.
1009 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1010 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$.
1011 ///
1012 /// If the output has a precision, it is `prec`.
1013 ///
1014 /// Special cases:
1015 /// - $f(0,p,m)=-\infty$
1016 /// - $f(x,p,m)=\text{NaN}$ for $x<0$
1017 /// - $f(1,p,m)=0.0$, and the result is exact
1018 /// - $f(2^k,p,m)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
1019 /// representable with precision $p$. This includes negative powers of 2 like $1/4$, and
1020 /// powers of 2 whose exponents $k$ lie far outside the exponent range of [`Float`]; the
1021 /// result is just the integer $k$ as a [`Float`].
1022 ///
1023 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_2_rational_prec`]
1024 /// instead.
1025 ///
1026 /// # Worst-case complexity
1027 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
1028 ///
1029 /// $M(n, m) = O(n \log n + m)$
1030 ///
1031 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1032 /// `x.significant_bits()`.
1033 ///
1034 /// # Panics
1035 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1036 /// with the given precision. (The result is exactly representable if and only if $x\leq 0$ or
1037 /// $x$ is a power of 2 whose base-2 logarithm is representable with the given precision.)
1038 ///
1039 /// # Examples
1040 /// ```
1041 /// use malachite_base::rounding_modes::RoundingMode::*;
1042 /// use malachite_float::Float;
1043 /// use malachite_q::Rational;
1044 /// use std::cmp::Ordering::*;
1045 ///
1046 /// let (log, o) =
1047 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1048 /// assert_eq!(log.to_string(), "-0.750");
1049 /// assert_eq!(o, Less);
1050 ///
1051 /// let (log, o) =
1052 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1053 /// assert_eq!(log.to_string(), "-0.719");
1054 /// assert_eq!(o, Greater);
1055 ///
1056 /// let (log, o) =
1057 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Nearest);
1058 /// assert_eq!(log.to_string(), "-0.750");
1059 /// assert_eq!(o, Less);
1060 ///
1061 /// let (log, o) =
1062 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1063 /// assert_eq!(log.to_string(), "-0.73696613");
1064 /// assert_eq!(o, Less);
1065 ///
1066 /// let (log, o) =
1067 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1068 /// assert_eq!(log.to_string(), "-0.73696518");
1069 /// assert_eq!(o, Greater);
1070 ///
1071 /// let (log, o) =
1072 /// Float::log_base_2_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Nearest);
1073 /// assert_eq!(log.to_string(), "-0.73696518");
1074 /// assert_eq!(o, Greater);
1075 /// ```
1076 #[allow(clippy::needless_pass_by_value)]
1077 #[inline]
1078 pub fn log_base_2_rational_prec_round(
1079 x: Rational,
1080 prec: u64,
1081 rm: RoundingMode,
1082 ) -> (Self, Ordering) {
1083 Self::log_base_2_rational_prec_round_ref(&x, prec, rm)
1084 }
1085
1086 /// Computes $\log_2 x$, where $x$ is a [`Rational`], rounding the result to the specified
1087 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1088 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1089 /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
1090 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
1091 /// `Equal`.
1092 ///
1093 /// The base-2 logarithm of any negative number is `NaN`.
1094 ///
1095 /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1096 /// or too small to be representable as [`Float`]s.
1097 ///
1098 /// See [`RoundingMode`] for a description of the possible rounding modes.
1099 ///
1100 /// $$
1101 /// f(x,p,m) = \log_2 x+\varepsilon.
1102 /// $$
1103 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1104 /// 0.
1105 /// - If $\log_2 x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1106 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p+1}$.
1107 /// - If $\log_2 x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1108 /// 2^{\lfloor\log_2 |\log_2 x|\rfloor-p}$.
1109 ///
1110 /// If the output has a precision, it is `prec`.
1111 ///
1112 /// Special cases:
1113 /// - $f(0,p,m)=-\infty$
1114 /// - $f(x,p,m)=\text{NaN}$ for $x<0$
1115 /// - $f(1,p,m)=0.0$, and the result is exact
1116 /// - $f(2^k,p,m)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
1117 /// representable with precision $p$. This includes negative powers of 2 like $1/4$, and
1118 /// powers of 2 whose exponents $k$ lie far outside the exponent range of [`Float`]; the
1119 /// result is just the integer $k$ as a [`Float`].
1120 ///
1121 /// If you know you'll be using `Nearest`, consider using
1122 /// [`Float::log_base_2_rational_prec_ref`] instead.
1123 ///
1124 /// # Worst-case complexity
1125 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
1126 ///
1127 /// $M(n, m) = O(n \log n + m)$
1128 ///
1129 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1130 /// `x.significant_bits()`.
1131 ///
1132 /// # Panics
1133 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1134 /// with the given precision. (The result is exactly representable if and only if $x\leq 0$ or
1135 /// $x$ is a power of 2 whose base-2 logarithm is representable with the given precision.)
1136 ///
1137 /// # Examples
1138 /// ```
1139 /// use malachite_base::rounding_modes::RoundingMode::*;
1140 /// use malachite_float::Float;
1141 /// use malachite_q::Rational;
1142 /// use std::cmp::Ordering::*;
1143 ///
1144 /// let (log, o) =
1145 /// Float::log_base_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1146 /// assert_eq!(log.to_string(), "-0.750");
1147 /// assert_eq!(o, Less);
1148 ///
1149 /// let (log, o) = Float::log_base_2_rational_prec_round_ref(
1150 /// &Rational::from_unsigneds(3u8, 5),
1151 /// 5,
1152 /// Ceiling,
1153 /// );
1154 /// assert_eq!(log.to_string(), "-0.719");
1155 /// assert_eq!(o, Greater);
1156 ///
1157 /// let (log, o) = Float::log_base_2_rational_prec_round_ref(
1158 /// &Rational::from_unsigneds(3u8, 5),
1159 /// 5,
1160 /// Nearest,
1161 /// );
1162 /// assert_eq!(log.to_string(), "-0.750");
1163 /// assert_eq!(o, Less);
1164 ///
1165 /// let (log, o) =
1166 /// Float::log_base_2_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1167 /// assert_eq!(log.to_string(), "-0.73696613");
1168 /// assert_eq!(o, Less);
1169 ///
1170 /// let (log, o) = Float::log_base_2_rational_prec_round_ref(
1171 /// &Rational::from_unsigneds(3u8, 5),
1172 /// 20,
1173 /// Ceiling,
1174 /// );
1175 /// assert_eq!(log.to_string(), "-0.73696518");
1176 /// assert_eq!(o, Greater);
1177 ///
1178 /// let (log, o) = Float::log_base_2_rational_prec_round_ref(
1179 /// &Rational::from_unsigneds(3u8, 5),
1180 /// 20,
1181 /// Nearest,
1182 /// );
1183 /// assert_eq!(log.to_string(), "-0.73696518");
1184 /// assert_eq!(o, Greater);
1185 /// ```
1186 pub fn log_base_2_rational_prec_round_ref(
1187 x: &Rational,
1188 prec: u64,
1189 rm: RoundingMode,
1190 ) -> (Self, Ordering) {
1191 assert_ne!(prec, 0);
1192 match x.sign() {
1193 Equal => return (float_negative_infinity!(), Equal),
1194 Less => return (float_nan!(), Equal),
1195 Greater => {}
1196 }
1197 // If x is 2^k, log_base_2(x) is exact (though possibly subject to rounding at the target
1198 // precision).
1199 if let Some(k) = x.checked_log_base_2() {
1200 return Self::from_signed_prec_round(k, prec, rm);
1201 }
1202 // The result is never exactly representable for other inputs.
1203 assert_ne!(rm, Exact, "Inexact log_base_2");
1204 log_base_2_rational_prec_round_helper(x, prec, rm)
1205 }
1206
1207 /// Computes $\log_2 x$, where $x$ is a [`Rational`], rounding the result to the nearest value
1208 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1209 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded value is
1210 /// less than, equal to, or greater than the exact value. Although `NaN`s are not comparable to
1211 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1212 ///
1213 /// The base-2 logarithm of any negative number is `NaN`.
1214 ///
1215 /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1216 /// or too small to be representable as [`Float`]s.
1217 ///
1218 /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
1219 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1220 /// description of the `Nearest` rounding mode.
1221 ///
1222 /// $$
1223 /// f(x,p) = \log_2 x+\varepsilon.
1224 /// $$
1225 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1226 /// 0.
1227 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
1228 /// x|\rfloor-p}$.
1229 ///
1230 /// If the output has a precision, it is `prec`.
1231 ///
1232 /// Special cases:
1233 /// - $f(0,p)=-\infty$
1234 /// - $f(x,p)=\text{NaN}$ for $x<0$
1235 /// - $f(1,p)=0.0$, and the result is exact
1236 /// - $f(2^k,p)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
1237 /// representable with precision $p$. This includes negative powers of 2 like $1/4$, and
1238 /// powers of 2 whose exponents $k$ lie far outside the exponent range of [`Float`]; the
1239 /// result is just the integer $k$ as a [`Float`].
1240 ///
1241 /// If you want to use a rounding mode other than `Nearest`, consider using
1242 /// [`Float::log_base_2_rational_prec_round`] instead.
1243 ///
1244 /// # Worst-case complexity
1245 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
1246 ///
1247 /// $M(n, m) = O(n \log n + m)$
1248 ///
1249 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1250 /// `x.significant_bits()`.
1251 ///
1252 /// # Panics
1253 /// Panics if `prec` is zero.
1254 ///
1255 /// # Examples
1256 /// ```
1257 /// use malachite_float::Float;
1258 /// use malachite_q::Rational;
1259 /// use std::cmp::Ordering::*;
1260 ///
1261 /// let (log, o) = Float::log_base_2_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1262 /// assert_eq!(log.to_string(), "-0.750");
1263 /// assert_eq!(o, Less);
1264 ///
1265 /// let (log, o) = Float::log_base_2_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1266 /// assert_eq!(log.to_string(), "-0.73696518");
1267 /// assert_eq!(o, Greater);
1268 /// ```
1269 #[inline]
1270 pub fn log_base_2_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1271 Self::log_base_2_rational_prec_round(x, prec, Nearest)
1272 }
1273
1274 /// Computes $\log_2 x$, where $x$ is a [`Rational`], rounding the result to the nearest value
1275 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1276 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded value
1277 /// is less than, equal to, or greater than the exact value. Although `NaN`s are not comparable
1278 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1279 ///
1280 /// The base-2 logarithm of any negative number is `NaN`.
1281 ///
1282 /// Inputs of any magnitude are handled, including [`Rational`]s whose magnitudes are too large
1283 /// or too small to be representable as [`Float`]s.
1284 ///
1285 /// If the logarithm is equidistant from two [`Float`]s with the specified precision, the
1286 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1287 /// description of the `Nearest` rounding mode.
1288 ///
1289 /// $$
1290 /// f(x,p) = \log_2 x+\varepsilon.
1291 /// $$
1292 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1293 /// 0.
1294 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
1295 /// x|\rfloor-p}$.
1296 ///
1297 /// If the output has a precision, it is `prec`.
1298 ///
1299 /// Special cases:
1300 /// - $f(0,p)=-\infty$
1301 /// - $f(x,p)=\text{NaN}$ for $x<0$
1302 /// - $f(1,p)=0.0$, and the result is exact
1303 /// - $f(2^k,p)=k$, rounded to precision $p$; the result is exact if and only if $k$ is
1304 /// representable with precision $p$. This includes negative powers of 2 like $1/4$, and
1305 /// powers of 2 whose exponents $k$ lie far outside the exponent range of [`Float`]; the
1306 /// result is just the integer $k$ as a [`Float`].
1307 ///
1308 /// If you want to use a rounding mode other than `Nearest`, consider using
1309 /// [`Float::log_base_2_rational_prec_round_ref`] instead.
1310 ///
1311 /// # Worst-case complexity
1312 /// $T(n, m) = O(n (\log n)^2 \log\log n + m)$
1313 ///
1314 /// $M(n, m) = O(n \log n + m)$
1315 ///
1316 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1317 /// `x.significant_bits()`.
1318 ///
1319 /// # Panics
1320 /// Panics if `prec` is zero.
1321 ///
1322 /// # Examples
1323 /// ```
1324 /// use malachite_float::Float;
1325 /// use malachite_q::Rational;
1326 /// use std::cmp::Ordering::*;
1327 ///
1328 /// let (log, o) = Float::log_base_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1329 /// assert_eq!(log.to_string(), "-0.750");
1330 /// assert_eq!(o, Less);
1331 ///
1332 /// let (log, o) = Float::log_base_2_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1333 /// assert_eq!(log.to_string(), "-0.73696518");
1334 /// assert_eq!(o, Greater);
1335 /// ```
1336 #[inline]
1337 pub fn log_base_2_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1338 Self::log_base_2_rational_prec_round_ref(x, prec, Nearest)
1339 }
1340}
1341
1342impl LogBase2 for Float {
1343 type Output = Self;
1344
1345 /// Computes $\log_2 x$, where $x$ is a [`Float`], taking it by value.
1346 ///
1347 /// If the output has a precision, it is the precision of the input. If the logarithm is
1348 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1349 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1350 /// rounding mode.
1351 ///
1352 /// The base-2 logarithm of any nonzero negative number is `NaN`.
1353 ///
1354 /// $$
1355 /// f(x) = \log_2 x+\varepsilon.
1356 /// $$
1357 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1358 /// 0.
1359 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
1360 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1361 ///
1362 /// Special cases:
1363 /// - $f(\text{NaN})=\text{NaN}$
1364 /// - $f(\infty)=\infty$
1365 /// - $f(-\infty)=\text{NaN}$
1366 /// - $f(\pm0.0)=-\infty$
1367 /// - $f(1.0)=0.0$, and the result is exact
1368 /// - $f(2^k)=k$, rounded to the precision of the input; the result is exact if and only if $k$
1369 /// is representable with that precision
1370 /// - $f(x)=\text{NaN}$ for $x<0$
1371 ///
1372 /// Neither overflow nor underflow is possible.
1373 ///
1374 /// If you want to use a rounding mode other than `Nearest`, consider using
1375 /// [`Float::log_base_2_round`] instead. If you want to specify the output precision, consider
1376 /// using [`Float::log_base_2_prec`]. If you want both of these things, consider using
1377 /// [`Float::log_base_2_prec_round`].
1378 ///
1379 /// # Worst-case complexity
1380 /// $T(n) = O(n (\log n)^2 \log\log n)$
1381 ///
1382 /// $M(n) = O(n \log n)$
1383 ///
1384 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1385 ///
1386 /// # Examples
1387 /// ```
1388 /// use malachite_base::num::arithmetic::traits::LogBase2;
1389 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1390 /// use malachite_float::Float;
1391 ///
1392 /// assert!(Float::NAN.log_base_2().is_nan());
1393 /// assert_eq!(Float::INFINITY.log_base_2(), Float::INFINITY);
1394 /// assert!(Float::NEGATIVE_INFINITY.log_base_2().is_nan());
1395 /// assert_eq!(
1396 /// Float::from_unsigned_prec(10u32, 100)
1397 /// .0
1398 /// .log_base_2()
1399 /// .to_string(),
1400 /// "3.3219280948873623478703194294898"
1401 /// );
1402 /// assert!(Float::from_signed_prec(-10, 100).0.log_base_2().is_nan());
1403 /// ```
1404 #[inline]
1405 fn log_base_2(self) -> Self {
1406 let prec = self.significant_bits();
1407 self.log_base_2_prec_round(prec, Nearest).0
1408 }
1409}
1410
1411impl LogBase2 for &Float {
1412 type Output = Float;
1413
1414 /// Computes $\log_2 x$, where $x$ is a [`Float`], taking it by reference.
1415 ///
1416 /// If the output has a precision, it is the precision of the input. If the logarithm is
1417 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1418 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1419 /// rounding mode.
1420 ///
1421 /// The base-2 logarithm of any nonzero negative number is `NaN`.
1422 ///
1423 /// $$
1424 /// f(x) = \log_2 x+\varepsilon.
1425 /// $$
1426 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1427 /// 0.
1428 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
1429 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1430 ///
1431 /// Special cases:
1432 /// - $f(\text{NaN})=\text{NaN}$
1433 /// - $f(\infty)=\infty$
1434 /// - $f(-\infty)=\text{NaN}$
1435 /// - $f(\pm0.0)=-\infty$
1436 /// - $f(1.0)=0.0$, and the result is exact
1437 /// - $f(2^k)=k$, rounded to the precision of the input; the result is exact if and only if $k$
1438 /// is representable with that precision
1439 /// - $f(x)=\text{NaN}$ for $x<0$
1440 ///
1441 /// Neither overflow nor underflow is possible.
1442 ///
1443 /// If you want to use a rounding mode other than `Nearest`, consider using
1444 /// [`Float::log_base_2_round_ref`] instead. If you want to specify the output precision,
1445 /// consider using [`Float::log_base_2_prec_ref`]. If you want both of these things, consider
1446 /// using [`Float::log_base_2_prec_round_ref`].
1447 ///
1448 /// # Worst-case complexity
1449 /// $T(n) = O(n (\log n)^2 \log\log n)$
1450 ///
1451 /// $M(n) = O(n \log n)$
1452 ///
1453 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1454 ///
1455 /// # Examples
1456 /// ```
1457 /// use malachite_base::num::arithmetic::traits::LogBase2;
1458 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1459 /// use malachite_float::Float;
1460 ///
1461 /// assert!((&Float::NAN).log_base_2().is_nan());
1462 /// assert_eq!((&Float::INFINITY).log_base_2(), Float::INFINITY);
1463 /// assert!((&Float::NEGATIVE_INFINITY).log_base_2().is_nan());
1464 /// assert_eq!(
1465 /// (&Float::from_unsigned_prec(10u32, 100).0)
1466 /// .log_base_2()
1467 /// .to_string(),
1468 /// "3.3219280948873623478703194294898"
1469 /// );
1470 /// assert!((&Float::from_signed_prec(-10, 100).0).log_base_2().is_nan());
1471 /// ```
1472 #[inline]
1473 fn log_base_2(self) -> Float {
1474 let prec = self.significant_bits();
1475 self.log_base_2_prec_round_ref(prec, Nearest).0
1476 }
1477}
1478
1479impl LogBase2Assign for Float {
1480 /// Computes $\log_2 x$, where $x$ is a [`Float`], in place.
1481 ///
1482 /// If the output has a precision, it is the precision of the input. If the logarithm is
1483 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1484 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1485 /// rounding mode.
1486 ///
1487 /// The base-2 logarithm of any nonzero negative number is `NaN`.
1488 ///
1489 /// $$
1490 /// x \gets \log_2 x+\varepsilon.
1491 /// $$
1492 /// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1493 /// 0.
1494 /// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\log_2
1495 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1496 ///
1497 /// See the [`Float::log_base_2`] documentation for information on special cases, overflow, and
1498 /// underflow.
1499 ///
1500 /// If you want to use a rounding mode other than `Nearest`, consider using
1501 /// [`Float::log_base_2_round_assign`] instead. If you want to specify the output precision,
1502 /// consider using [`Float::log_base_2_prec_assign`]. If you want both of these things, consider
1503 /// using [`Float::log_base_2_prec_round_assign`].
1504 ///
1505 /// # Worst-case complexity
1506 /// $T(n) = O(n (\log n)^2 \log\log n)$
1507 ///
1508 /// $M(n) = O(n \log n)$
1509 ///
1510 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1511 ///
1512 /// # Examples
1513 /// ```
1514 /// use malachite_base::num::arithmetic::traits::LogBase2Assign;
1515 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
1516 /// use malachite_float::Float;
1517 ///
1518 /// let mut x = Float::NAN;
1519 /// x.log_base_2_assign();
1520 /// assert!(x.is_nan());
1521 ///
1522 /// let mut x = Float::INFINITY;
1523 /// x.log_base_2_assign();
1524 /// assert_eq!(x, Float::INFINITY);
1525 ///
1526 /// let mut x = Float::NEGATIVE_INFINITY;
1527 /// x.log_base_2_assign();
1528 /// assert!(x.is_nan());
1529 ///
1530 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
1531 /// x.log_base_2_assign();
1532 /// assert_eq!(x.to_string(), "3.3219280948873623478703194294898");
1533 ///
1534 /// let mut x = Float::from_signed_prec(-10, 100).0;
1535 /// x.log_base_2_assign();
1536 /// assert!(x.is_nan());
1537 /// ```
1538 #[inline]
1539 fn log_base_2_assign(&mut self) {
1540 let prec = self.significant_bits();
1541 self.log_base_2_prec_round_assign(prec, Nearest);
1542 }
1543}
1544
1545/// Computes the base-2 logarithm of a primitive float, $\log_2 x$.
1546///
1547/// This function is correctly rounded. The standard library's `log2` is correctly rounded for
1548/// [`f32`] but not always for [`f64`], so for some [`f64`] inputs this function is more accurate.
1549///
1550/// The base-2 logarithm of any nonzero negative number is `NaN`.
1551///
1552/// $$
1553/// f(x) = \log_2 x+\varepsilon.
1554/// $$
1555/// - If $\log_2 x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1556/// - If $\log_2 x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |\log_2
1557/// x|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53
1558/// if `T` is a [`f64`], but less if the output is subnormal).
1559///
1560/// Special cases:
1561/// - $f(\text{NaN})=\text{NaN}$
1562/// - $f(\infty)=\infty$
1563/// - $f(-\infty)=\text{NaN}$
1564/// - $f(\pm0.0)=-\infty$
1565/// - $f(x)=\text{NaN}$ for $x<0$
1566///
1567/// Neither overflow nor underflow is possible.
1568///
1569/// # Worst-case complexity
1570/// Constant time and additional memory.
1571///
1572/// # Examples
1573/// ```
1574/// use malachite_base::num::basic::traits::NegativeInfinity;
1575/// use malachite_base::num::float::NiceFloat;
1576/// use malachite_float::float::arithmetic::log_base_2::primitive_float_log_base_2;
1577///
1578/// assert!(primitive_float_log_base_2(f32::NAN).is_nan());
1579/// assert_eq!(
1580/// NiceFloat(primitive_float_log_base_2(f32::INFINITY)),
1581/// NiceFloat(f32::INFINITY)
1582/// );
1583/// assert!(primitive_float_log_base_2(f32::NEGATIVE_INFINITY).is_nan());
1584/// assert_eq!(
1585/// NiceFloat(primitive_float_log_base_2(0.0f32)),
1586/// NiceFloat(f32::NEGATIVE_INFINITY)
1587/// );
1588/// assert_eq!(
1589/// NiceFloat(primitive_float_log_base_2(8.0f32)),
1590/// NiceFloat(3.0)
1591/// );
1592/// assert_eq!(
1593/// NiceFloat(primitive_float_log_base_2(10.0f32)),
1594/// NiceFloat(3.321928)
1595/// );
1596/// assert!(primitive_float_log_base_2(-10.0f32).is_nan());
1597/// ```
1598#[inline]
1599#[allow(clippy::type_repetition_in_bounds)]
1600pub fn primitive_float_log_base_2<T: PrimitiveFloat>(x: T) -> T
1601where
1602 Float: From<T> + PartialOrd<T>,
1603 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1604{
1605 emulate_float_to_float_fn(Float::log_base_2_prec, x)
1606}
1607
1608/// Computes the base-2 logarithm of a [`Rational`], returning a primitive float result.
1609///
1610/// If the logarithm is equidistant from two primitive floats, the primitive float with fewer 1s in
1611/// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest` rounding
1612/// mode.
1613///
1614/// The logarithm of any negative number is `NaN`.
1615///
1616/// $$
1617/// f(x) = \log_2{x}+\varepsilon.
1618/// $$
1619/// - If $\log_2{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1620/// - If $\log_2{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1621/// |\log_2{x}|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`]
1622/// and 53 if `T` is a [`f64`], but less if the output is subnormal).
1623///
1624/// Special cases:
1625/// - $f(0)=-\infty$
1626///
1627/// Neither overflow nor underflow is possible.
1628///
1629/// # Worst-case complexity
1630/// $T(m) = O(m)$
1631///
1632/// $M(m) = O(m)$
1633///
1634/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
1635///
1636/// # Examples
1637/// ```
1638/// use malachite_base::num::basic::traits::{NegativeInfinity, Zero};
1639/// use malachite_base::num::float::NiceFloat;
1640/// use malachite_float::float::arithmetic::log_base_2::primitive_float_log_base_2_rational;
1641/// use malachite_q::Rational;
1642///
1643/// assert_eq!(
1644/// NiceFloat(primitive_float_log_base_2_rational::<f64>(&Rational::ZERO)),
1645/// NiceFloat(f64::NEGATIVE_INFINITY)
1646/// );
1647/// assert_eq!(
1648/// NiceFloat(primitive_float_log_base_2_rational::<f64>(
1649/// &Rational::from_unsigneds(1u8, 3)
1650/// )),
1651/// NiceFloat(-1.584962500721156)
1652/// );
1653/// assert_eq!(
1654/// NiceFloat(primitive_float_log_base_2_rational::<f64>(&Rational::from(
1655/// 10000
1656/// ))),
1657/// NiceFloat(13.287712379549449)
1658/// );
1659/// assert_eq!(
1660/// NiceFloat(primitive_float_log_base_2_rational::<f64>(&Rational::from(
1661/// -10000
1662/// ))),
1663/// NiceFloat(f64::NAN)
1664/// );
1665/// ```
1666#[inline]
1667#[allow(clippy::type_repetition_in_bounds)]
1668pub fn primitive_float_log_base_2_rational<T: PrimitiveFloat>(x: &Rational) -> T
1669where
1670 Float: PartialOrd<T>,
1671 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1672{
1673 emulate_rational_to_float_fn(Float::log_base_2_rational_prec_ref, x)
1674}