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