malachite_float/arithmetic/log_base_2_1_plus_x.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright 2001-2026 Free Software Foundation, Inc.
6//
7// Contributed by the AriC and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::InnerFloat::{Infinity, NaN, Zero};
16use crate::{Float, emulate_float_to_float_fn, float_infinity, float_nan, float_negative_infinity};
17use core::cmp::Ordering::{self, *};
18use core::cmp::max;
19use malachite_base::num::arithmetic::traits::{
20 CeilingLogBase2, IsPowerOf2, LogBase2Of1PlusX, LogBase2Of1PlusXAssign,
21};
22use malachite_base::num::basic::floats::PrimitiveFloat;
23use malachite_base::num::basic::integers::PrimitiveInt;
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::{
28 float_can_round, float_significand_leading_ones,
29};
30use malachite_nz::platform::Limb;
31
32// Returns `Some(k)` if `1 + x` is exactly $2^k$ (equivalently $x = 2^k - 1$), and `None` otherwise.
33// The input must be finite, nonzero, and greater than $-1$.
34//
35// `1 + x` is a power of 2 exactly when the mantissa of `x` is a run of ones (the value $2^j - 1$),
36// the exponent of `x` equals $j$ (so `x` is the integer $2^j - 1$ and $k = j$) when `x` is
37// positive, or the exponent of `x` is 0 (so `x` is $-(1 - 2^{-j})$ and $k = -j$) when `x` is
38// negative. This replaces MPFR's `mpfr_log2p1_isexact`, which adds 1 to `x` and tests for a power
39// of 2; we test the significand's bits directly.
40pub(crate) fn log_base_2_1_plus_x_exact(x: &Float) -> Option<i64> {
41 let j = i64::exact_from(float_significand_leading_ones(
42 x.significand_ref().unwrap(),
43 )?);
44 let e = i64::from(x.get_exponent().unwrap());
45 if *x > 0u32 {
46 (e == j).then_some(j)
47 } else {
48 (e == 0).then_some(-j)
49 }
50}
51
52// If `x` is $2^k$ for a `k` large enough that the Ziv loop would never converge, returns the
53// correctly-rounded value of $\log_2(1+x)$; otherwise returns `None`. The input must be finite,
54// nonzero, and greater than $-1$, and `1 + x` must not be a power of 2.
55//
56// This is mpfr_log2p1_special from log2p1.c, MPFR 4.3.0. For $x = 2^k$ with $k \geq 1$ we have $k <
57// \log_2(1+x) < k + 2/x$. When $2/x$ is below a quarter of an ulp of $k$, the result rounds the
58// same way as $k$ stepped up by a single ulp, so the rounding can be decided directly.
59fn log_base_2_1_plus_x_special(
60 x: &Float,
61 prec: u64,
62 rm: RoundingMode,
63) -> Option<(Float, Ordering)> {
64 if !x.is_power_of_2() {
65 return None;
66 }
67 let expx = i64::from(x.get_exponent().unwrap());
68 // x = 2^k
69 let k = expx - 1;
70 if k <= 0 {
71 return None;
72 }
73 // expk is the exponent of k. We have 2 / x < 2^(2 - expx), so if 2 - expx < expk - prec - 1,
74 // then 2 / x < (1/4) ulp(k) and the correct rounding can be decided.
75 let expk = i64::exact_from(u64::exact_from(k).ceiling_log_base_2());
76 if 2 - expx >= expk - i64::exact_from(prec) - 1 {
77 return None;
78 }
79 // log_2(1 + x) lies in (k, k + 1/4 ulp(k)); round k stepped up by one ulp.
80 let high_prec = max(prec + 2, Limb::WIDTH);
81 let mut t = Float::from_signed_prec(k, high_prec).0;
82 t.increment();
83 Some(Float::from_float_prec_round(t, prec, rm))
84}
85
86// The computation of log2p1 is done by log_base_2_1_plus_x(x) = ln_1_plus_x(x) / ln(2).
87//
88// This is mpfr_log2p1 from log2p1.c, MPFR 4.3.0, where the input is finite and nonzero.
89fn log_base_2_1_plus_x_prec_round_normal(
90 x: &Float,
91 prec: u64,
92 rm: RoundingMode,
93) -> (Float, Ordering) {
94 // log_2(1 + x) is undefined for x < -1.
95 match x.partial_cmp(&-1i32).unwrap() {
96 Equal => return (float_negative_infinity!(), Equal),
97 Less => return (float_nan!(), Equal),
98 _ => {}
99 }
100 // If 1 + x is exactly a power of 2, the result is an integer (subject to rounding at the target
101 // precision).
102 if let Some(k) = log_base_2_1_plus_x_exact(x) {
103 return Float::from_signed_prec_round(k, prec, rm);
104 }
105 // The result is never exactly representable otherwise.
106 assert_ne!(rm, Exact, "Inexact log_base_2_1_plus_x");
107 // If x = 2^k with k huge, the Ziv loop would never converge; handle it specially.
108 if let Some(result) = log_base_2_1_plus_x_special(x, prec, rm) {
109 return result;
110 }
111 // General case. Compute the precision of the intermediary variable: the optimal number of bits,
112 // see algorithms.tex.
113 let mut working_prec = prec + prec.ceiling_log_base_2() + 6;
114 let mut increment = Limb::WIDTH;
115 loop {
116 // ln(1 + x) / ln(2). This is log_2(1 + x) * (1 + theta)^3 with |theta| < 2^-working_prec,
117 // and |(1 + theta)^3 - 1| < 4 * theta for working_prec >= 2, i.e. 4 ulps of error.
118 let t = x
119 .ln_1_plus_x_prec_ref(working_prec)
120 .0
121 .div_prec(Float::ln_2_prec(working_prec).0, working_prec)
122 .0;
123 if float_can_round(t.significand_ref().unwrap(), working_prec - 2, prec, rm) {
124 return Float::from_float_prec_round(t, prec, rm);
125 }
126 // Increase the precision.
127 working_prec += increment;
128 increment = working_prec >> 1;
129 }
130}
131
132impl Float {
133 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result to the specified
134 /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
135 /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
136 /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
137 /// whenever this function returns a `NaN` it also returns `Equal`.
138 ///
139 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
140 ///
141 /// See [`RoundingMode`] for a description of the possible rounding modes.
142 ///
143 /// $$
144 /// f(x,p,m) = \log_2(1+x)+\varepsilon.
145 /// $$
146 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
147 /// be 0.
148 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
149 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$.
150 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
151 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$.
152 ///
153 /// If the output has a precision, it is `prec`.
154 ///
155 /// Special cases:
156 /// - $f(\text{NaN},p,m)=\text{NaN}$
157 /// - $f(\infty,p,m)=\infty$
158 /// - $f(-\infty,p,m)=\text{NaN}$
159 /// - $f(\pm0.0,p,m)=\pm0.0$
160 /// - $f(-1,p,m)=-\infty$
161 /// - $f(x,p,m)=\text{NaN}$ for $x<-1$
162 /// - $f(x,p,m)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at
163 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
164 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
165 /// $x=-3/4\to-2$.
166 ///
167 /// Neither overflow nor underflow is possible.
168 ///
169 /// If you know you'll be using `Nearest`, consider using [`Float::log_base_2_1_plus_x_prec`]
170 /// instead. If you know that your target precision is the precision of the input, consider
171 /// using [`Float::log_base_2_1_plus_x_round`] instead. If both of these things are true,
172 /// consider using [`Float::log_base_2_1_plus_x`] instead.
173 ///
174 /// # Worst-case complexity
175 /// $T(n) = O(n (\log n)^2 \log\log n)$
176 ///
177 /// $M(n) = O(n (\log n)^2)$
178 ///
179 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
180 ///
181 /// # Panics
182 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
183 /// with the given precision. (The result is exactly representable only when the input is `NaN`,
184 /// infinite, zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose
185 /// base-2 logarithm is representable with the given precision.)
186 ///
187 /// # Examples
188 /// ```
189 /// use malachite_base::rounding_modes::RoundingMode::*;
190 /// use malachite_float::Float;
191 /// use std::cmp::Ordering::*;
192 ///
193 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
194 /// .0
195 /// .log_base_2_1_plus_x_prec_round(5, Floor);
196 /// assert_eq!(log.to_string(), "3.4");
197 /// assert_eq!(o, Less);
198 ///
199 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
200 /// .0
201 /// .log_base_2_1_plus_x_prec_round(5, Ceiling);
202 /// assert_eq!(log.to_string(), "3.5");
203 /// assert_eq!(o, Greater);
204 ///
205 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
206 /// .0
207 /// .log_base_2_1_plus_x_prec_round(5, Nearest);
208 /// assert_eq!(log.to_string(), "3.5");
209 /// assert_eq!(o, Greater);
210 ///
211 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
212 /// .0
213 /// .log_base_2_1_plus_x_prec_round(20, Floor);
214 /// assert_eq!(log.to_string(), "3.459431");
215 /// assert_eq!(o, Less);
216 ///
217 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
218 /// .0
219 /// .log_base_2_1_plus_x_prec_round(20, Ceiling);
220 /// assert_eq!(log.to_string(), "3.459435");
221 /// assert_eq!(o, Greater);
222 ///
223 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
224 /// .0
225 /// .log_base_2_1_plus_x_prec_round(20, Nearest);
226 /// assert_eq!(log.to_string(), "3.459431");
227 /// assert_eq!(o, Less);
228 /// ```
229 #[inline]
230 pub fn log_base_2_1_plus_x_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
231 assert_ne!(prec, 0);
232 match self {
233 Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
234 float_infinity!() => (float_infinity!(), Equal),
235 // log_base_2_1_plus_x(±0) = ±0
236 Self(Zero { .. }) => (self, Equal),
237 _ => log_base_2_1_plus_x_prec_round_normal(&self, prec, rm),
238 }
239 }
240
241 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result to the specified
242 /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
243 /// [`Ordering`] is also returned, indicating whether the rounded value is less than, equal to,
244 /// or greater than the exact value. Although `NaN`s are not comparable to any [`Float`],
245 /// whenever this function returns a `NaN` it also returns `Equal`.
246 ///
247 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
248 ///
249 /// See [`RoundingMode`] for a description of the possible rounding modes.
250 ///
251 /// $$
252 /// f(x,p,m) = \log_2(1+x)+\varepsilon.
253 /// $$
254 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
255 /// be 0.
256 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
257 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$.
258 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
259 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$.
260 ///
261 /// If the output has a precision, it is `prec`.
262 ///
263 /// Special cases:
264 /// - $f(\text{NaN},p,m)=\text{NaN}$
265 /// - $f(\infty,p,m)=\infty$
266 /// - $f(-\infty,p,m)=\text{NaN}$
267 /// - $f(\pm0.0,p,m)=\pm0.0$
268 /// - $f(-1,p,m)=-\infty$
269 /// - $f(x,p,m)=\text{NaN}$ for $x<-1$
270 /// - $f(x,p,m)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at
271 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
272 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
273 /// $x=-3/4\to-2$.
274 ///
275 /// Neither overflow nor underflow is possible.
276 ///
277 /// If you know you'll be using `Nearest`, consider using
278 /// [`Float::log_base_2_1_plus_x_prec_ref`] instead. If you know that your target precision is
279 /// the precision of the input, consider using [`Float::log_base_2_1_plus_x_round_ref`] instead.
280 /// If both of these things are true, consider using `(&Float).log_base_2_1_plus_x()` instead.
281 ///
282 /// # Worst-case complexity
283 /// $T(n) = O(n (\log n)^2 \log\log n)$
284 ///
285 /// $M(n) = O(n (\log n)^2)$
286 ///
287 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
288 ///
289 /// # Panics
290 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
291 /// with the given precision. (The result is exactly representable only when the input is `NaN`,
292 /// infinite, zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose
293 /// base-2 logarithm is representable with the given precision.)
294 ///
295 /// # Examples
296 /// ```
297 /// use malachite_base::rounding_modes::RoundingMode::*;
298 /// use malachite_float::Float;
299 /// use std::cmp::Ordering::*;
300 ///
301 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
302 /// .0
303 /// .log_base_2_1_plus_x_prec_round_ref(5, Floor);
304 /// assert_eq!(log.to_string(), "3.4");
305 /// assert_eq!(o, Less);
306 ///
307 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
308 /// .0
309 /// .log_base_2_1_plus_x_prec_round_ref(5, Ceiling);
310 /// assert_eq!(log.to_string(), "3.5");
311 /// assert_eq!(o, Greater);
312 ///
313 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
314 /// .0
315 /// .log_base_2_1_plus_x_prec_round_ref(5, Nearest);
316 /// assert_eq!(log.to_string(), "3.5");
317 /// assert_eq!(o, Greater);
318 ///
319 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
320 /// .0
321 /// .log_base_2_1_plus_x_prec_round_ref(20, Floor);
322 /// assert_eq!(log.to_string(), "3.459431");
323 /// assert_eq!(o, Less);
324 ///
325 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
326 /// .0
327 /// .log_base_2_1_plus_x_prec_round_ref(20, Ceiling);
328 /// assert_eq!(log.to_string(), "3.459435");
329 /// assert_eq!(o, Greater);
330 ///
331 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
332 /// .0
333 /// .log_base_2_1_plus_x_prec_round_ref(20, Nearest);
334 /// assert_eq!(log.to_string(), "3.459431");
335 /// assert_eq!(o, Less);
336 /// ```
337 #[inline]
338 pub fn log_base_2_1_plus_x_prec_round_ref(
339 &self,
340 prec: u64,
341 rm: RoundingMode,
342 ) -> (Self, Ordering) {
343 assert_ne!(prec, 0);
344 match self {
345 Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
346 float_infinity!() => (float_infinity!(), Equal),
347 // log_base_2_1_plus_x(±0) = ±0
348 Self(Zero { .. }) => (self.clone(), Equal),
349 _ => log_base_2_1_plus_x_prec_round_normal(self, prec, rm),
350 }
351 }
352
353 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest value
354 /// of the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also
355 /// returned, indicating whether the rounded value is less than, equal to, or greater than the
356 /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
357 /// returns a `NaN` it also returns `Equal`.
358 ///
359 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
360 ///
361 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
362 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
363 /// the `Nearest` rounding mode.
364 ///
365 /// $$
366 /// f(x,p) = \log_2(1+x)+\varepsilon.
367 /// $$
368 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
369 /// be 0.
370 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
371 /// |\log_2(1+x)|\rfloor-p}$.
372 ///
373 /// If the output has a precision, it is `prec`.
374 ///
375 /// Special cases:
376 /// - $f(\text{NaN},p)=\text{NaN}$
377 /// - $f(\infty,p)=\infty$
378 /// - $f(-\infty,p)=\text{NaN}$
379 /// - $f(\pm0.0,p)=\pm0.0$
380 /// - $f(-1,p)=-\infty$
381 /// - $f(x,p)=\text{NaN}$ for $x<-1$
382 /// - $f(x,p)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at precision
383 /// $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a power of 2
384 /// minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
385 /// $x=-3/4\to-2$.
386 ///
387 /// Neither overflow nor underflow is possible.
388 ///
389 /// If you want to use a rounding mode other than `Nearest`, consider using
390 /// [`Float::log_base_2_1_plus_x_prec_round`] instead. If you know that your target precision is
391 /// the precision of the input, consider using [`Float::log_base_2_1_plus_x`] instead.
392 ///
393 /// # Worst-case complexity
394 /// $T(n) = O(n (\log n)^2 \log\log n)$
395 ///
396 /// $M(n) = O(n (\log n)^2)$
397 ///
398 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
399 ///
400 /// # Panics
401 /// Panics if `prec` is zero.
402 ///
403 /// # Examples
404 /// ```
405 /// use malachite_base::num::basic::traits::One;
406 /// use malachite_float::Float;
407 /// use std::cmp::Ordering::*;
408 ///
409 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
410 /// .0
411 /// .log_base_2_1_plus_x_prec(5);
412 /// assert_eq!(log.to_string(), "3.5");
413 /// assert_eq!(o, Greater);
414 ///
415 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
416 /// .0
417 /// .log_base_2_1_plus_x_prec(20);
418 /// assert_eq!(log.to_string(), "3.459431");
419 /// assert_eq!(o, Less);
420 ///
421 /// let (log, o) = Float::ONE.log_base_2_1_plus_x_prec(20);
422 /// assert_eq!(log.to_string(), "1.0");
423 /// assert_eq!(o, Equal);
424 /// ```
425 #[inline]
426 pub fn log_base_2_1_plus_x_prec(self, prec: u64) -> (Self, Ordering) {
427 self.log_base_2_1_plus_x_prec_round(prec, Nearest)
428 }
429
430 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result to the nearest value
431 /// of the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
432 /// returned, indicating whether the rounded value is less than, equal to, or greater than the
433 /// exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
434 /// returns a `NaN` it also returns `Equal`.
435 ///
436 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
437 ///
438 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
439 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
440 /// the `Nearest` rounding mode.
441 ///
442 /// $$
443 /// f(x,p) = \log_2(1+x)+\varepsilon.
444 /// $$
445 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
446 /// be 0.
447 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
448 /// |\log_2(1+x)|\rfloor-p}$.
449 ///
450 /// If the output has a precision, it is `prec`.
451 ///
452 /// Special cases:
453 /// - $f(\text{NaN},p)=\text{NaN}$
454 /// - $f(\infty,p)=\infty$
455 /// - $f(-\infty,p)=\text{NaN}$
456 /// - $f(\pm0.0,p)=\pm0.0$
457 /// - $f(-1,p)=-\infty$
458 /// - $f(x,p)=\text{NaN}$ for $x<-1$
459 /// - $f(x,p)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at precision
460 /// $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a power of 2
461 /// minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
462 /// $x=-3/4\to-2$.
463 ///
464 /// Neither overflow nor underflow is possible.
465 ///
466 /// If you want to use a rounding mode other than `Nearest`, consider using
467 /// [`Float::log_base_2_1_plus_x_prec_round_ref`] instead. If you know that your target
468 /// precision is the precision of the input, consider using `(&Float).log_base_2_1_plus_x()`
469 /// instead.
470 ///
471 /// # Worst-case complexity
472 /// $T(n) = O(n (\log n)^2 \log\log n)$
473 ///
474 /// $M(n) = O(n (\log n)^2)$
475 ///
476 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
477 ///
478 /// # Panics
479 /// Panics if `prec` is zero.
480 ///
481 /// # Examples
482 /// ```
483 /// use malachite_base::num::basic::traits::One;
484 /// use malachite_float::Float;
485 /// use std::cmp::Ordering::*;
486 ///
487 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
488 /// .0
489 /// .log_base_2_1_plus_x_prec_ref(5);
490 /// assert_eq!(log.to_string(), "3.5");
491 /// assert_eq!(o, Greater);
492 ///
493 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
494 /// .0
495 /// .log_base_2_1_plus_x_prec_ref(20);
496 /// assert_eq!(log.to_string(), "3.459431");
497 /// assert_eq!(o, Less);
498 ///
499 /// let (log, o) = Float::ONE.log_base_2_1_plus_x_prec_ref(20);
500 /// assert_eq!(log.to_string(), "1.0");
501 /// assert_eq!(o, Equal);
502 /// ```
503 #[inline]
504 pub fn log_base_2_1_plus_x_prec_ref(&self, prec: u64) -> (Self, Ordering) {
505 self.log_base_2_1_plus_x_prec_round_ref(prec, Nearest)
506 }
507
508 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result with the specified
509 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
510 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
511 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
512 /// returns `Equal`.
513 ///
514 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
515 ///
516 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
517 /// description of the possible rounding modes.
518 ///
519 /// $$
520 /// f(x,m) = \log_2(1+x)+\varepsilon.
521 /// $$
522 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
523 /// be 0.
524 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
525 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$, where $p$ is the precision of the input.
526 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
527 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
528 ///
529 /// If the output has a precision, it is the precision of the input.
530 ///
531 /// Special cases:
532 /// - $f(\text{NaN},m)=\text{NaN}$
533 /// - $f(\infty,m)=\infty$
534 /// - $f(-\infty,m)=\text{NaN}$
535 /// - $f(\pm0.0,m)=\pm0.0$
536 /// - $f(-1,m)=-\infty$
537 /// - $f(x,m)=\text{NaN}$ for $x<-1$
538 /// - $f(x,m)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at the input
539 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
540 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
541 /// $x=-3/4\to-2$.
542 ///
543 /// Neither overflow nor underflow is possible.
544 ///
545 /// If you want to specify an output precision, consider using
546 /// [`Float::log_base_2_1_plus_x_prec_round`] instead. If you know you'll be using the `Nearest`
547 /// rounding mode, consider using [`Float::log_base_2_1_plus_x`] instead.
548 ///
549 /// # Worst-case complexity
550 /// $T(n) = O(n (\log n)^2 \log\log n)$
551 ///
552 /// $M(n) = O(n (\log n)^2)$
553 ///
554 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
555 ///
556 /// # Panics
557 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
558 /// precision. (The result is exactly representable only when the input is `NaN`, infinite,
559 /// zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose base-2
560 /// logarithm is representable with the given precision.)
561 ///
562 /// # Examples
563 /// ```
564 /// use malachite_base::rounding_modes::RoundingMode::*;
565 /// use malachite_float::Float;
566 /// use std::cmp::Ordering::*;
567 ///
568 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
569 /// .0
570 /// .log_base_2_1_plus_x_round(Floor);
571 /// assert_eq!(log.to_string(), "3.459431618637297256199363046725");
572 /// assert_eq!(o, Less);
573 ///
574 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
575 /// .0
576 /// .log_base_2_1_plus_x_round(Ceiling);
577 /// assert_eq!(log.to_string(), "3.459431618637297256199363046728");
578 /// assert_eq!(o, Greater);
579 ///
580 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
581 /// .0
582 /// .log_base_2_1_plus_x_round(Nearest);
583 /// assert_eq!(log.to_string(), "3.459431618637297256199363046725");
584 /// assert_eq!(o, Less);
585 /// ```
586 #[inline]
587 pub fn log_base_2_1_plus_x_round(self, rm: RoundingMode) -> (Self, Ordering) {
588 let prec = self.significant_bits();
589 self.log_base_2_1_plus_x_prec_round(prec, rm)
590 }
591
592 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], rounding the result with the specified
593 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
594 /// indicating whether the rounded value is less than, equal to, or greater than the exact
595 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
596 /// `NaN` it also returns `Equal`.
597 ///
598 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
599 ///
600 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
601 /// description of the possible rounding modes.
602 ///
603 /// $$
604 /// f(x,m) = \log_2(1+x)+\varepsilon.
605 /// $$
606 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
607 /// be 0.
608 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
609 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$, where $p$ is the precision of the input.
610 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
611 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
612 ///
613 /// If the output has a precision, it is the precision of the input.
614 ///
615 /// Special cases:
616 /// - $f(\text{NaN},m)=\text{NaN}$
617 /// - $f(\infty,m)=\infty$
618 /// - $f(-\infty,m)=\text{NaN}$
619 /// - $f(\pm0.0,m)=\pm0.0$
620 /// - $f(-1,m)=-\infty$
621 /// - $f(x,m)=\text{NaN}$ for $x<-1$
622 /// - $f(x,m)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at the input
623 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
624 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
625 /// $x=-3/4\to-2$.
626 ///
627 /// Neither overflow nor underflow is possible.
628 ///
629 /// If you want to specify an output precision, consider using
630 /// [`Float::log_base_2_1_plus_x_prec_round_ref`] instead. If you know you'll be using the
631 /// `Nearest` rounding mode, consider using `(&Float).log_base_2_1_plus_x()` instead.
632 ///
633 /// # Worst-case complexity
634 /// $T(n) = O(n (\log n)^2 \log\log n)$
635 ///
636 /// $M(n) = O(n (\log n)^2)$
637 ///
638 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
639 ///
640 /// # Panics
641 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
642 /// precision. (The result is exactly representable only when the input is `NaN`, infinite,
643 /// zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose base-2
644 /// logarithm is representable with the given precision.)
645 ///
646 /// # Examples
647 /// ```
648 /// use malachite_base::rounding_modes::RoundingMode::*;
649 /// use malachite_float::Float;
650 /// use std::cmp::Ordering::*;
651 ///
652 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
653 /// .0
654 /// .log_base_2_1_plus_x_round_ref(Floor);
655 /// assert_eq!(log.to_string(), "3.459431618637297256199363046725");
656 /// assert_eq!(o, Less);
657 ///
658 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
659 /// .0
660 /// .log_base_2_1_plus_x_round_ref(Ceiling);
661 /// assert_eq!(log.to_string(), "3.459431618637297256199363046728");
662 /// assert_eq!(o, Greater);
663 ///
664 /// let (log, o) = Float::from_unsigned_prec(10u32, 100)
665 /// .0
666 /// .log_base_2_1_plus_x_round_ref(Nearest);
667 /// assert_eq!(log.to_string(), "3.459431618637297256199363046725");
668 /// assert_eq!(o, Less);
669 /// ```
670 #[inline]
671 pub fn log_base_2_1_plus_x_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
672 let prec = self.significant_bits();
673 self.log_base_2_1_plus_x_prec_round_ref(prec, rm)
674 }
675
676 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], in place, rounding the result to the
677 /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
678 /// indicating whether the rounded value is less than, equal to, or greater than the exact
679 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
680 /// [`Float`] to `NaN` it also returns `Equal`.
681 ///
682 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to `NaN`.
683 ///
684 /// See [`RoundingMode`] for a description of the possible rounding modes.
685 ///
686 /// $$
687 /// x \gets \log_2(1+x)+\varepsilon.
688 /// $$
689 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
690 /// be 0.
691 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
692 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$.
693 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
694 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$.
695 ///
696 /// If the output has a precision, it is `prec`.
697 ///
698 /// See the [`Float::log_base_2_1_plus_x_prec_round`] documentation for information on special
699 /// cases, overflow, and underflow.
700 ///
701 /// If you know you'll be using `Nearest`, consider using
702 /// [`Float::log_base_2_1_plus_x_prec_assign`] instead. If you know that your target precision
703 /// is the precision of the input, consider using [`Float::log_base_2_1_plus_x_round_assign`]
704 /// instead. If both of these things are true, consider using
705 /// [`Float::log_base_2_1_plus_x_assign`] instead.
706 ///
707 /// # Worst-case complexity
708 /// $T(n) = O(n (\log n)^2 \log\log n)$
709 ///
710 /// $M(n) = O(n (\log n)^2)$
711 ///
712 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
713 ///
714 /// # Panics
715 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
716 /// with the given precision. (The result is exactly representable only when the input is `NaN`,
717 /// infinite, zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose
718 /// base-2 logarithm is representable with the given precision.)
719 ///
720 /// # Examples
721 /// ```
722 /// use malachite_base::rounding_modes::RoundingMode::*;
723 /// use malachite_float::Float;
724 /// use std::cmp::Ordering::*;
725 ///
726 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
727 /// assert_eq!(x.log_base_2_1_plus_x_prec_round_assign(5, Floor), Less);
728 /// assert_eq!(x.to_string(), "3.4");
729 ///
730 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
731 /// assert_eq!(x.log_base_2_1_plus_x_prec_round_assign(5, Ceiling), Greater);
732 /// assert_eq!(x.to_string(), "3.5");
733 ///
734 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
735 /// assert_eq!(x.log_base_2_1_plus_x_prec_round_assign(5, Nearest), Greater);
736 /// assert_eq!(x.to_string(), "3.5");
737 ///
738 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
739 /// assert_eq!(x.log_base_2_1_plus_x_prec_round_assign(20, Floor), Less);
740 /// assert_eq!(x.to_string(), "3.459431");
741 ///
742 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
743 /// assert_eq!(
744 /// x.log_base_2_1_plus_x_prec_round_assign(20, Ceiling),
745 /// Greater
746 /// );
747 /// assert_eq!(x.to_string(), "3.459435");
748 ///
749 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
750 /// assert_eq!(x.log_base_2_1_plus_x_prec_round_assign(20, Nearest), Less);
751 /// assert_eq!(x.to_string(), "3.459431");
752 /// ```
753 #[inline]
754 pub fn log_base_2_1_plus_x_prec_round_assign(
755 &mut self,
756 prec: u64,
757 rm: RoundingMode,
758 ) -> Ordering {
759 let (result, o) = core::mem::take(self).log_base_2_1_plus_x_prec_round(prec, rm);
760 *self = result;
761 o
762 }
763
764 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], in place, rounding the result to the
765 /// nearest value of the specified precision. An [`Ordering`] is returned, indicating whether
766 /// the rounded value is less than, equal to, or greater than the exact value. Although `NaN`s
767 /// are not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it
768 /// also returns `Equal`.
769 ///
770 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to `NaN`.
771 ///
772 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
773 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
774 /// the `Nearest` rounding mode.
775 ///
776 /// $$
777 /// x \gets \log_2(1+x)+\varepsilon.
778 /// $$
779 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
780 /// be 0.
781 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
782 /// |\log_2(1+x)|\rfloor-p}$.
783 ///
784 /// If the output has a precision, it is `prec`.
785 ///
786 /// See the [`Float::log_base_2_1_plus_x_prec`] documentation for information on special cases,
787 /// overflow, and underflow.
788 ///
789 /// If you want to use a rounding mode other than `Nearest`, consider using
790 /// [`Float::log_base_2_1_plus_x_prec_round_assign`] instead. If you know that your target
791 /// precision is the precision of the input, consider using
792 /// [`Float::log_base_2_1_plus_x_assign`] instead.
793 ///
794 /// # Worst-case complexity
795 /// $T(n) = O(n (\log n)^2 \log\log n)$
796 ///
797 /// $M(n) = O(n (\log n)^2)$
798 ///
799 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
800 ///
801 /// # Panics
802 /// Panics if `prec` is zero.
803 ///
804 /// # Examples
805 /// ```
806 /// use malachite_float::Float;
807 /// use std::cmp::Ordering::*;
808 ///
809 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
810 /// assert_eq!(x.log_base_2_1_plus_x_prec_assign(5), Greater);
811 /// assert_eq!(x.to_string(), "3.5");
812 ///
813 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
814 /// assert_eq!(x.log_base_2_1_plus_x_prec_assign(20), Less);
815 /// assert_eq!(x.to_string(), "3.459431");
816 /// ```
817 #[inline]
818 pub fn log_base_2_1_plus_x_prec_assign(&mut self, prec: u64) -> Ordering {
819 self.log_base_2_1_plus_x_prec_round_assign(prec, Nearest)
820 }
821
822 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], in place, rounding the result with the
823 /// specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded value
824 /// is less than, equal to, or greater than the exact value. Although `NaN`s are not comparable
825 /// to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns
826 /// `Equal`.
827 ///
828 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to `NaN`.
829 ///
830 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
831 /// description of the possible rounding modes.
832 ///
833 /// $$
834 /// x \gets \log_2(1+x)+\varepsilon.
835 /// $$
836 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
837 /// be 0.
838 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
839 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p+1}$, where $p$ is the precision of the input.
840 /// - If $\log_2(1+x)$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
841 /// 2^{\lfloor\log_2 |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
842 ///
843 /// If the output has a precision, it is the precision of the input.
844 ///
845 /// See the [`Float::log_base_2_1_plus_x_round`] documentation for information on special cases,
846 /// overflow, and underflow.
847 ///
848 /// If you want to specify an output precision, consider using
849 /// [`Float::log_base_2_1_plus_x_prec_round_assign`] instead. If you know you'll be using the
850 /// `Nearest` rounding mode, consider using [`Float::log_base_2_1_plus_x_assign`] instead.
851 ///
852 /// # Worst-case complexity
853 /// $T(n) = O(n (\log n)^2 \log\log n)$
854 ///
855 /// $M(n) = O(n (\log n)^2)$
856 ///
857 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
858 ///
859 /// # Panics
860 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
861 /// precision. (The result is exactly representable only when the input is `NaN`, infinite,
862 /// zero, $-1$, less than $-1$, or a value for which $1+x$ is a power of 2 whose base-2
863 /// logarithm is representable with the given precision.)
864 ///
865 /// # Examples
866 /// ```
867 /// use malachite_base::rounding_modes::RoundingMode::*;
868 /// use malachite_float::Float;
869 /// use std::cmp::Ordering::*;
870 ///
871 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
872 /// assert_eq!(x.log_base_2_1_plus_x_round_assign(Floor), Less);
873 /// assert_eq!(x.to_string(), "3.459431618637297256199363046725");
874 ///
875 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
876 /// assert_eq!(x.log_base_2_1_plus_x_round_assign(Ceiling), Greater);
877 /// assert_eq!(x.to_string(), "3.459431618637297256199363046728");
878 ///
879 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
880 /// assert_eq!(x.log_base_2_1_plus_x_round_assign(Nearest), Less);
881 /// assert_eq!(x.to_string(), "3.459431618637297256199363046725");
882 /// ```
883 #[inline]
884 pub fn log_base_2_1_plus_x_round_assign(&mut self, rm: RoundingMode) -> Ordering {
885 let prec = self.significant_bits();
886 self.log_base_2_1_plus_x_prec_round_assign(prec, rm)
887 }
888}
889
890impl LogBase2Of1PlusX for Float {
891 type Output = Self;
892
893 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], taking the [`Float`] by value.
894 ///
895 /// If the output has a precision, it is the precision of the input. If the result is
896 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
897 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
898 /// rounding mode.
899 ///
900 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
901 ///
902 /// $$
903 /// f(x) = \log_2(1+x)+\varepsilon.
904 /// $$
905 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
906 /// be 0.
907 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
908 /// |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
909 ///
910 /// Special cases:
911 /// - $f(\text{NaN})=\text{NaN}$
912 /// - $f(\infty)=\infty$
913 /// - $f(-\infty)=\text{NaN}$
914 /// - $f(\pm0.0)=\pm0.0$
915 /// - $f(-1)=-\infty$
916 /// - $f(x)=\text{NaN}$ for $x<-1$
917 /// - $f(x)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at the input
918 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
919 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
920 /// $x=-3/4\to-2$.
921 ///
922 /// Neither overflow nor underflow is possible.
923 ///
924 /// If you want to use a rounding mode other than `Nearest`, consider using
925 /// [`Float::log_base_2_1_plus_x_round`] instead. If you want to specify the output precision,
926 /// consider using [`Float::log_base_2_1_plus_x_prec`]. If you want both of these things,
927 /// consider using [`Float::log_base_2_1_plus_x_prec_round`].
928 ///
929 /// # Worst-case complexity
930 /// $T(n) = O(n (\log n)^2 \log\log n)$
931 ///
932 /// $M(n) = O(n (\log n)^2)$
933 ///
934 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
935 ///
936 /// # Examples
937 /// ```
938 /// use malachite_base::num::arithmetic::traits::LogBase2Of1PlusX;
939 /// use malachite_base::num::basic::traits::{
940 /// Infinity, NaN, NegativeInfinity, NegativeOne, One,
941 /// };
942 /// use malachite_float::Float;
943 ///
944 /// assert!(Float::NAN.log_base_2_1_plus_x().is_nan());
945 /// assert_eq!(Float::INFINITY.log_base_2_1_plus_x(), Float::INFINITY);
946 /// assert!(Float::NEGATIVE_INFINITY.log_base_2_1_plus_x().is_nan());
947 /// assert_eq!(Float::ONE.log_base_2_1_plus_x().to_string(), "1.0");
948 /// assert_eq!(
949 /// Float::from_unsigned_prec(10u32, 100)
950 /// .0
951 /// .log_base_2_1_plus_x()
952 /// .to_string(),
953 /// "3.459431618637297256199363046725"
954 /// );
955 /// assert_eq!(
956 /// Float::NEGATIVE_ONE.log_base_2_1_plus_x(),
957 /// Float::NEGATIVE_INFINITY
958 /// );
959 /// assert!(Float::from_signed_prec(-10, 100)
960 /// .0
961 /// .log_base_2_1_plus_x()
962 /// .is_nan());
963 /// ```
964 #[inline]
965 fn log_base_2_1_plus_x(self) -> Self {
966 let prec = self.significant_bits();
967 self.log_base_2_1_plus_x_prec_round(prec, Nearest).0
968 }
969}
970
971impl LogBase2Of1PlusX for &Float {
972 type Output = Float;
973
974 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], taking the [`Float`] by reference.
975 ///
976 /// If the output has a precision, it is the precision of the input. If the result is
977 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
978 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
979 /// rounding mode.
980 ///
981 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
982 ///
983 /// $$
984 /// f(x) = \log_2(1+x)+\varepsilon.
985 /// $$
986 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
987 /// be 0.
988 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
989 /// |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
990 ///
991 /// Special cases:
992 /// - $f(\text{NaN})=\text{NaN}$
993 /// - $f(\infty)=\infty$
994 /// - $f(-\infty)=\text{NaN}$
995 /// - $f(\pm0.0)=\pm0.0$
996 /// - $f(-1)=-\infty$
997 /// - $f(x)=\text{NaN}$ for $x<-1$
998 /// - $f(x)=k$ when $1+x=2^k$. The result is the integer $k$ (subject to rounding at the input
999 /// precision $p$, and exact iff $k$ is representable with precision $p$). This covers $x$ a
1000 /// power of 2 minus 1 (e.g. $x=1\to1$, $x=3\to2$) and negative $x$ such as $x=-1/2\to-1$ and
1001 /// $x=-3/4\to-2$.
1002 ///
1003 /// Neither overflow nor underflow is possible.
1004 ///
1005 /// If you want to use a rounding mode other than `Nearest`, consider using
1006 /// [`Float::log_base_2_1_plus_x_round_ref`] instead. If you want to specify the output
1007 /// precision, consider using [`Float::log_base_2_1_plus_x_prec_ref`]. If you want both of these
1008 /// things, consider using [`Float::log_base_2_1_plus_x_prec_round_ref`].
1009 ///
1010 /// # Worst-case complexity
1011 /// $T(n) = O(n (\log n)^2 \log\log n)$
1012 ///
1013 /// $M(n) = O(n (\log n)^2)$
1014 ///
1015 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1016 ///
1017 /// # Examples
1018 /// ```
1019 /// use malachite_base::num::arithmetic::traits::LogBase2Of1PlusX;
1020 /// use malachite_base::num::basic::traits::{
1021 /// Infinity, NaN, NegativeInfinity, NegativeOne, One,
1022 /// };
1023 /// use malachite_float::Float;
1024 ///
1025 /// assert!((&Float::NAN).log_base_2_1_plus_x().is_nan());
1026 /// assert_eq!((&Float::INFINITY).log_base_2_1_plus_x(), Float::INFINITY);
1027 /// assert!((&Float::NEGATIVE_INFINITY).log_base_2_1_plus_x().is_nan());
1028 /// assert_eq!((&Float::ONE).log_base_2_1_plus_x().to_string(), "1.0");
1029 /// assert_eq!(
1030 /// (&Float::from_unsigned_prec(10u32, 100).0)
1031 /// .log_base_2_1_plus_x()
1032 /// .to_string(),
1033 /// "3.459431618637297256199363046725"
1034 /// );
1035 /// assert_eq!(
1036 /// (&Float::NEGATIVE_ONE).log_base_2_1_plus_x(),
1037 /// Float::NEGATIVE_INFINITY
1038 /// );
1039 /// assert!((&Float::from_signed_prec(-10, 100).0)
1040 /// .log_base_2_1_plus_x()
1041 /// .is_nan());
1042 /// ```
1043 #[inline]
1044 fn log_base_2_1_plus_x(self) -> Float {
1045 let prec = self.significant_bits();
1046 self.log_base_2_1_plus_x_prec_round_ref(prec, Nearest).0
1047 }
1048}
1049
1050impl LogBase2Of1PlusXAssign for Float {
1051 /// Computes $\log_2(1+x)$, where $x$ is a [`Float`], in place.
1052 ///
1053 /// If the output has a precision, it is the precision of the input. If the result is
1054 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1055 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1056 /// rounding mode.
1057 ///
1058 /// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, the [`Float`] is set to `NaN`.
1059 ///
1060 /// $$
1061 /// x \gets \log_2(1+x)+\varepsilon.
1062 /// $$
1063 /// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
1064 /// be 0.
1065 /// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1066 /// |\log_2(1+x)|\rfloor-p}$, where $p$ is the precision of the input.
1067 ///
1068 /// See the [`Float::log_base_2_1_plus_x`] documentation for information on special cases,
1069 /// overflow, and underflow.
1070 ///
1071 /// If you want to use a rounding mode other than `Nearest`, consider using
1072 /// [`Float::log_base_2_1_plus_x_round_assign`] instead. If you want to specify the output
1073 /// precision, consider using [`Float::log_base_2_1_plus_x_prec_assign`]. If you want both of
1074 /// these things, consider using [`Float::log_base_2_1_plus_x_prec_round_assign`].
1075 ///
1076 /// # Worst-case complexity
1077 /// $T(n) = O(n (\log n)^2 \log\log n)$
1078 ///
1079 /// $M(n) = O(n (\log n)^2)$
1080 ///
1081 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1082 ///
1083 /// # Examples
1084 /// ```
1085 /// use malachite_base::num::arithmetic::traits::LogBase2Of1PlusXAssign;
1086 /// use malachite_base::num::basic::traits::{
1087 /// Infinity, NaN, NegativeInfinity, NegativeOne, One,
1088 /// };
1089 /// use malachite_float::Float;
1090 ///
1091 /// let mut x = Float::NAN;
1092 /// x.log_base_2_1_plus_x_assign();
1093 /// assert!(x.is_nan());
1094 ///
1095 /// let mut x = Float::INFINITY;
1096 /// x.log_base_2_1_plus_x_assign();
1097 /// assert_eq!(x, Float::INFINITY);
1098 ///
1099 /// let mut x = Float::NEGATIVE_INFINITY;
1100 /// x.log_base_2_1_plus_x_assign();
1101 /// assert!(x.is_nan());
1102 ///
1103 /// let mut x = Float::ONE;
1104 /// x.log_base_2_1_plus_x_assign();
1105 /// assert_eq!(x.to_string(), "1.0");
1106 ///
1107 /// let mut x = Float::from_unsigned_prec(10u32, 100).0;
1108 /// x.log_base_2_1_plus_x_assign();
1109 /// assert_eq!(x.to_string(), "3.459431618637297256199363046725");
1110 ///
1111 /// let mut x = Float::NEGATIVE_ONE;
1112 /// x.log_base_2_1_plus_x_assign();
1113 /// assert_eq!(x, Float::NEGATIVE_INFINITY);
1114 ///
1115 /// let mut x = Float::from_signed_prec(-10, 100).0;
1116 /// x.log_base_2_1_plus_x_assign();
1117 /// assert!(x.is_nan());
1118 /// ```
1119 #[inline]
1120 fn log_base_2_1_plus_x_assign(&mut self) {
1121 let prec = self.significant_bits();
1122 self.log_base_2_1_plus_x_prec_round_assign(prec, Nearest);
1123 }
1124}
1125
1126/// Computes the base-2 logarithm of one plus a primitive float, $\log_2(1+x)$. Using this function
1127/// is more accurate than computing `(1 + x).log2()`, both because $1+x$ may not be representable as
1128/// a primitive float and because the standard library's `log2` is not always correctly rounded.
1129///
1130/// $\log_2(1+x)$ is undefined for $x<-1$, so whenever $x<-1$, `NaN` is returned.
1131///
1132/// $$
1133/// f(x) = \log_2(1+x)+\varepsilon.
1134/// $$
1135/// - If $\log_2(1+x)$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1136/// - If $\log_2(1+x)$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1137/// |\log_2(1+x)|\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a
1138/// [`f32`] and 53 if `T` is a [`f64`], but less if the output is subnormal).
1139///
1140/// Special cases:
1141/// - $f(\text{NaN})=\text{NaN}$
1142/// - $f(\infty)=\infty$
1143/// - $f(-\infty)=\text{NaN}$
1144/// - $f(\pm0.0)=\pm0.0$
1145/// - $f(-1.0)=-\infty$
1146/// - $f(x)=\text{NaN}$ for $x<-1$
1147///
1148/// Neither overflow nor underflow is possible.
1149///
1150/// # Worst-case complexity
1151/// Constant time and additional memory.
1152///
1153/// # Examples
1154/// ```
1155/// use malachite_base::num::basic::traits::NegativeInfinity;
1156/// use malachite_base::num::float::NiceFloat;
1157/// use malachite_float::arithmetic::log_base_2_1_plus_x::primitive_float_log_base_2_1_plus_x;
1158///
1159/// assert!(primitive_float_log_base_2_1_plus_x(f32::NAN).is_nan());
1160/// assert_eq!(
1161/// NiceFloat(primitive_float_log_base_2_1_plus_x(f32::INFINITY)),
1162/// NiceFloat(f32::INFINITY)
1163/// );
1164/// assert!(primitive_float_log_base_2_1_plus_x(f32::NEGATIVE_INFINITY).is_nan());
1165/// assert_eq!(
1166/// NiceFloat(primitive_float_log_base_2_1_plus_x(-1.0f32)),
1167/// NiceFloat(f32::NEGATIVE_INFINITY)
1168/// );
1169/// assert!(primitive_float_log_base_2_1_plus_x(-2.0f32).is_nan());
1170/// assert_eq!(
1171/// NiceFloat(primitive_float_log_base_2_1_plus_x(1.0f32)),
1172/// NiceFloat(1.0)
1173/// );
1174/// assert_eq!(
1175/// NiceFloat(primitive_float_log_base_2_1_plus_x(7.0f32)),
1176/// NiceFloat(3.0)
1177/// );
1178/// ```
1179#[inline]
1180#[allow(clippy::type_repetition_in_bounds)]
1181pub fn primitive_float_log_base_2_1_plus_x<T: PrimitiveFloat>(x: T) -> T
1182where
1183 Float: From<T> + PartialOrd<T>,
1184 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1185{
1186 emulate_float_to_float_fn(Float::log_base_2_1_plus_x_prec, x)
1187}