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