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