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