malachite_float/float/arithmetic/exp_x_minus_1.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright 2001-2026 Free Software Foundation, Inc.
6//
7// Contributed by the Pascaline and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::InnerFloat::{Infinity, NaN, Zero};
16use crate::TWICE_WIDTH;
17use crate::float::arithmetic::exp::{exp_overflow, one_neighbor};
18use crate::float::arithmetic::round_near_x::float_round_near_x;
19use crate::{
20 Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, float_infinity, float_nan,
21 float_zero, floor_and_ceiling,
22};
23use core::cmp::Ordering::{self, *};
24use core::cmp::max;
25use malachite_base::num::arithmetic::traits::{
26 CeilingLogBase2, ExpXMinus1, ExpXMinus1Assign, PowerOf2, Sign,
27};
28use malachite_base::num::basic::floats::PrimitiveFloat;
29use malachite_base::num::basic::integers::PrimitiveInt;
30use malachite_base::num::basic::traits::{NegativeOne, One, Zero as ZeroTrait};
31use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom, SaturatingFrom};
32use malachite_base::num::logic::traits::SignificantBits;
33use malachite_base::rounding_modes::RoundingMode::{self, *};
34use malachite_nz::integer::Integer;
35use malachite_nz::natural::arithmetic::float_extras::float_can_round;
36use malachite_nz::platform::{Limb, SignedLimb};
37use malachite_q::Rational;
38
39// This is mpfr_expm1 from expm1.c, MPFR 4.2.2, where the input is finite and nonzero.
40fn exp_x_minus_1_prec_round_normal(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
41 let ex = i64::from(x.get_exponent().unwrap());
42 if ex < 0 {
43 // -0.5 < x < 0.5. For 0 < x < 1, |expm1(x) - x| < x^2. For -1 < x < 0, |expm1(x) - x| < x^2
44 // / 2. In both cases the error term is positive (expm1(x) > x), so it brings the result
45 // away from zero for x > 0 and toward zero for x < 0.
46 let (err, dir) = if *x > 0u32 {
47 (-ex, true)
48 } else {
49 (-ex + 1, false)
50 };
51 let err = u64::exact_from(err);
52 if err > prec + 1
53 && let Some(result) = float_round_near_x(x, err, dir, prec, rm)
54 {
55 return result;
56 }
57 }
58 // x negative in the smallest binade: |expm1(x)| < |x| can fall below the smallest positive
59 // Float even though x is representable, and the subtraction in the general loop below would
60 // saturate at exactly -min_positive -- a power-of-2 significand whose all-zero error window
61 // `float_can_round` never certifies, so the loop would grow forever. (This mirrors
62 // `power_of_2_x_minus_1`'s smallest-binade guard; positive x needs none, since expm1(x) > x.)
63 // The rational near-zero helper computes the result exactly, underflow rounding included; it is
64 // only reached when the shortcut above failed, i.e. at prec >= -MIN_EXPONENT.
65 if x.is_sign_negative() && ex == i64::from(Float::MIN_EXPONENT) {
66 return exp_x_minus_1_rational_near_zero(&Rational::exact_from(x), prec, rm);
67 }
68 // The result is never exactly representable for finite nonzero x.
69 assert_ne!(rm, Exact, "Inexact exp_x_minus_1");
70 const BP: u64 = 64;
71 if x.is_sign_negative() && ex > 5 {
72 // x <= -32, so exp(x) is tiny and expm1(x) = exp(x) - 1 is very close to -1 (slightly
73 // toward zero). Since exp(x) = 2^(x / ln(2)), an upper bound on x / ln(2) (obtained by
74 // dividing the negative x by an upper bound on ln(2)) gives an err with exp(x) < 2^(1 -
75 // err), so -1 can be rounded directly. This also handles the regime where exp(x) would
76 // underflow.
77 let log2_up = Float::ln_2_prec_round(BP, Up).0;
78 // Round the (negative) quotient toward +infinity to get an upper bound on x / ln(2). This
79 // must be `Ceiling`, not `Up`: for hugely negative x, rounding away from zero would push
80 // the magnitude past `MAX_EXPONENT` and overflow to -infinity, whereas `Ceiling` saturates
81 // to the largest finite value.
82 let t = x.div_prec_round_ref_val(log2_up, BP, Ceiling).0; // > x / ln(2)
83 // err = -ceil(t), clamped to at most MAX_EXPONENT. When |t| >= 2^31 > MAX_EXPONENT the
84 // clamp is decided from t's exponent alone: materializing t as an Integer just to compare
85 // it against a 31-bit constant would allocate up to ~2^30 bits (~128 MB) for hugely
86 // negative x. s_est is a lower bound on |x| / ln(2), used by the deep-negative helper.
87 let exp_t = i64::from(t.get_exponent().unwrap());
88 let (clamped, err, s_est) = if exp_t > 31 {
89 (
90 true,
91 u64::exact_from(Float::MAX_EXPONENT),
92 if exp_t > 64 {
93 u64::MAX
94 } else {
95 u64::power_of_2(u64::exact_from(exp_t - 1))
96 },
97 )
98 } else {
99 let neg_ceil = -Integer::rounding_from(&t, Ceiling).0;
100 const MAX_EXP: Integer = Integer::const_from_signed(Float::MAX_EXPONENT as SignedLimb);
101 let clamped = neg_ceil >= MAX_EXP;
102 let err = if clamped {
103 u64::exact_from(Float::MAX_EXPONENT)
104 } else {
105 u64::exact_from(&neg_ceil)
106 };
107 (clamped, err, u64::saturating_from(&neg_ceil))
108 };
109 if let Some(result) = float_round_near_x(&Float::NEGATIVE_ONE, err, false, prec, rm) {
110 return result;
111 }
112 // `float_round_near_x` could not resolve the rounding, so prec + 1 >= err. If the clamp was
113 // active, |x| / ln(2) can exceed MAX_EXPONENT: exp(x) may lie below the smallest positive
114 // Float (so the loop below could not compute it), while prec is so large that the bits of
115 // e^x may still land within the output's prec-bit window. Delegate to the deep-negative
116 // helper. (Without the clamp, err = neg_ceil <= prec + 1, and neg_ceil < MAX_EXPONENT puts
117 // |x| / ln(2) < neg_ceil + 2 <= 2^30 = |MIN_EXPONENT - 1|, so exp(x) does not underflow and
118 // the loop below handles it.)
119 if clamped {
120 return exp_x_minus_1_deep_negative(x, prec, rm, s_est);
121 }
122 }
123 // General case. Compute the precision of the intermediary variable: the optimal number of bits,
124 // see algorithms.tex.
125 let mut working_prec = prec + prec.ceiling_log_base_2() + 6;
126 // If |x| is smaller than 2^(-e), we lose about e bits in the subtraction exp(x) - 1.
127 if ex < 0 {
128 working_prec += u64::exact_from(-ex);
129 }
130 let mut increment = Limb::WIDTH;
131 loop {
132 // exp(x) may overflow.
133 let mut t = x.exp_prec_ref(working_prec).0;
134 if t.is_infinite() {
135 return exp_overflow(prec, rm);
136 }
137 // exp(x) cannot underflow here: that would require x / ln(2) < MIN_EXPONENT - 1, but then
138 // the large-negative case above would already have returned.
139 let exp_te = i64::from(t.get_exponent().unwrap());
140 t.sub_prec_assign(Float::ONE, working_prec); // exp(x) - 1
141 let t_exp = i64::from(t.get_exponent().unwrap());
142 // The error estimate (cf. expm1.c). The cancellation `max(exp_te - t_exp, 0)` never reaches
143 // `working_prec`: when |x| is small the cancellation is about -ex bits, which
144 // `working_prec` already absorbs via the `+= -ex` above, so `err` stays positive.
145 let err = working_prec - u64::exact_from(max(exp_te - t_exp, 0) + 1);
146 if float_can_round(t.significand_ref().unwrap(), err, prec, rm) {
147 return Float::from_float_prec_round(t, prec, rm);
148 }
149 // Increase the precision.
150 working_prec += increment;
151 increment = working_prec >> 1;
152 }
153}
154
155// Computes e^x - 1 for a Float x so negative that e^x lies at or below the smallest positive Float
156// (or nearly so: |x| / ln(2) >= MAX_EXPONENT), while prec + 1 >= MAX_EXPONENT, so rounding from -1
157// cannot be certified. e^x is not representable, but since prec is enormous the bits of e^x may
158// still land within the output's prec-bit window and must be computed for real. Since e^x - 1 =
159// 2^(x / ln(2)) - 1, bracket y = x / ln(2) between dyadic Floats (y has magnitude about |x| / 0.7
160// -- an ordinary Float, even though 2^y is not) and apply the monotonically increasing
161// `power_of_2_x_minus_1_prec_round` to both ends, tightening the bracket Ziv-style until both round
162// identically. That function's own deep-negative machinery computes 2^(y_end) - 1 exactly where
163// needed, and its huge-negative shortcut keeps the ends cheap when |x| / ln(2) > prec + 1 (where
164// the result is just -1 or its neighbor). `s_est` is a lower bound on |x| / ln(2), used to size the
165// initial working precision: the result's leading ~|y| bits are a run of ones, so only about prec -
166// s_est bits of 2^y are needed.
167fn exp_x_minus_1_deep_negative(
168 x: &Float,
169 prec: u64,
170 rm: RoundingMode,
171 s_est: u64,
172) -> (Float, Ordering) {
173 // e^x's leading bit lies |y| = |x| / ln(2) positions below 1. When it falls entirely below the
174 // output's prec-bit window (s_est, a lower bound on |y|, is at least prec + 2, so e^x <=
175 // 2^(-prec - 2) is under half the gap between -1 and its toward-zero neighbor), the result
176 // rounds directly from -1. The bracket below must then not run at all: a y beyond the Float
177 // exponent range would convert to -infinity under Floor, pinning that end at exactly (-1,
178 // Equal) at every working precision -- under Ceiling or Down the ends could never agree.
179 // (`float_round_near_x` cannot make this decision: its err argument is clamped at MAX_EXPONENT,
180 // which prec meets or exceeds here.)
181 if s_est >= prec.saturating_add(2) {
182 return match rm {
183 Ceiling | Down => (-one_neighbor(prec, false), Greater), // -1 + ulp (toward zero)
184 _ => (-Float::one_prec(prec), Less), // -1
185 };
186 }
187 let xr = Rational::exact_from(x);
188 let mut working_prec = prec.saturating_add(2).saturating_sub(s_est) + TWICE_WIDTH;
189 let mut increment = Limb::WIDTH;
190 loop {
191 // ln_2_lo <= ln(2) <= ln_2_hi, as exact Rationals, from a single ln(2) computation.
192 let (ln_2_lo, ln_2_hi) = floor_and_ceiling(Float::ln_2_prec_round(working_prec, Floor));
193 // x < 0: dividing x by the smaller (larger) positive bound gives the more (less) negative
194 // quotient, so these exact Rationals bracket y.
195 let y_lo = &xr / Rational::exact_from(&ln_2_lo);
196 let y_hi = &xr / Rational::exact_from(&ln_2_hi);
197 // Widen to dyadic Floats, rounding outward.
198 let y_lo = Float::from_rational_prec_round(y_lo, working_prec, Floor).0;
199 let y_hi = Float::from_rational_prec_round(y_hi, working_prec, Ceiling).0;
200 let (e_lo, mut o_lo) = y_lo.power_of_2_x_minus_1_prec_round(prec, rm);
201 let (e_hi, mut o_hi) = y_hi.power_of_2_x_minus_1_prec_round(prec, rm);
202 // A bracket end that lands on an integer y makes 2^y - 1 exactly representable, rounding
203 // with `Equal`; the true value lies strictly between the ends, so the other end's ordering
204 // is the true one. (Both cannot be `Equal`: the ends are distinct and the function is
205 // strictly increasing.)
206 if o_lo == Equal {
207 o_lo = o_hi;
208 }
209 if o_hi == Equal {
210 o_hi = o_lo;
211 }
212 if o_lo == o_hi && e_lo == e_hi {
213 return (e_lo, o_lo);
214 }
215 working_prec += increment;
216 increment = working_prec >> 1;
217 }
218}
219
220// Computes `exp(x) - 1` for a nonzero `Rational` `x` with `|x| < 2^MIN_EXPONENT`, by summing its
221// Taylor series `sum_{k>=1} x^k / k!`. Used when `x` is so small that `expm1(x) ~ x` underflows:
222// the squeeze in `exp_x_minus_1_rational_helper` cannot bracket such an `x` (its Float bounds
223// collapse to 0). The series is bracketed between two rationals which are rounded with
224// `from_rational_prec_round` (which performs the underflow rounding) until both ends agree.
225pub(crate) fn exp_x_minus_1_rational_near_zero(
226 x: &Rational,
227 prec: u64,
228 rm: RoundingMode,
229) -> (Float, Ordering) {
230 let negative = *x < 0u32;
231 let mut s = Rational::ZERO; // partial sum S_{k-1}, starting at S_0 = 0
232 let mut term = Rational::ONE; // x^(k-1) / (k-1)!
233 let mut k = 1u64;
234 loop {
235 term *= x;
236 term /= Rational::from(k); // term = x^k / k!
237 let s_next = &s + &term; // S_k
238 let (lo, hi) = if negative {
239 // The terms alternate in sign with strictly decreasing magnitude (|x| / (k + 1) < 1),
240 // so expm1(x) lies between consecutive partial sums.
241 if s < s_next {
242 (s.clone(), s_next.clone())
243 } else {
244 (s_next.clone(), s.clone())
245 }
246 } else {
247 // Every term is positive, so S_k < expm1(x), and the remainder is bounded by t_{k+1} /
248 // (1
249 // - x).
250 let next = (&term * x) / Rational::from(k + 1); // t_{k+1}
251 (s_next.clone(), &s_next + next / (Rational::ONE - x))
252 };
253 s = s_next;
254 k += 1;
255 let (f_lo, mut o_lo) = Float::from_rational_prec_round_ref(&lo, prec, rm);
256 let (f_hi, mut o_hi) = Float::from_rational_prec_round_ref(&hi, prec, rm);
257 // A bound that is exactly representable at `prec` rounds with `Equal`; treat it as agreeing
258 // with the other bound. (`hi == 0` triggers this for small negative x, since 0 is exact.)
259 if o_lo == Equal {
260 o_lo = o_hi;
261 }
262 if o_hi == Equal {
263 o_hi = o_lo;
264 }
265 if o_lo == o_hi && f_lo == f_hi {
266 return (f_lo, o_lo);
267 }
268 }
269}
270
271// Computes `exp(x) - 1` for a nonzero `Rational` `x`, rounded to precision `prec` with rounding
272// mode `rm`. (`expm1(0) = 0` is handled by the caller.) Because the value at a nonzero rational is
273// transcendental, the result is never exactly representable, so `rm` must not be `Exact`.
274fn exp_x_minus_1_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
275 assert_ne!(rm, Exact, "Inexact exp_x_minus_1");
276 let positive = x.sign() == Greater;
277 let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
278 // x is too small to be represented as a normal Float (|x| < 2^MIN_EXPONENT). The squeeze below
279 // cannot bracket it (its Float bounds would be 0), so sum the Taylor series instead. expm1(x) ~
280 // x underflows, which `from_rational_prec_round` handles in the helper.
281 if exp_x <= Float::MIN_EXPONENT_I64 {
282 return exp_x_minus_1_rational_near_zero(x, prec, rm);
283 }
284 // |x| is too large to be a finite Float. For x > 0, expm1(x) overflows to +inf; for x < 0,
285 // expm1(x) = -1 + exp(x) tends to -1. Smaller x that still overflow are caught in the loop
286 // below.
287 if exp_x >= Float::MAX_EXPONENT_I64 {
288 if positive {
289 return exp_overflow(prec, rm);
290 }
291 // exp(x) is far below ulp(-1) at any precision, so expm1(x) rounds to -1 or its toward-zero
292 // neighbor.
293 let err = u64::exact_from(Float::MAX_EXPONENT);
294 if let Some(result) = float_round_near_x(&Float::NEGATIVE_ONE, err, false, prec, rm) {
295 return result;
296 }
297 // `prec` is enormous (>= MAX_EXPONENT), so `float_round_near_x` cannot resolve the
298 // rounding; but exp(x) is still far below ulp(-1), so -1 rounds the same way.
299 return match rm {
300 Ceiling | Down => (-one_neighbor(prec, false), Greater), // -1 + ulp (toward zero)
301 _ => (-Float::one_prec(prec), Less), // -1
302 };
303 }
304 // General case: bracket x between the Floats x_lo <= x <= x_hi, apply expm1 to both, and
305 // increase the working precision until the two bounds round to the same result. expm1 is
306 // monotonic, so once the bounds agree the exact expm1(x) (which lies between them) rounds the
307 // same way.
308 let mut working_prec = prec + 10;
309 let mut increment = Limb::WIDTH;
310 loop {
311 let (x_lo, x_o) = Float::from_rational_prec_round_ref(x, working_prec, Floor);
312 if x_o == Equal {
313 // x is exactly representable at `working_prec`, so expm1(x) is simply expm1(x_lo).
314 return x_lo.exp_x_minus_1_prec_round(prec, rm);
315 }
316 let (x_lo, x_hi) = floor_and_ceiling((x_lo, x_o));
317 // expm1 of a finite nonzero Float is transcendental, so it is never exact: both orderings
318 // are `Less` or `Greater`, never `Equal`.
319 let (e_lo, o_lo) = x_lo.exp_x_minus_1_prec_round_ref(prec, rm);
320 let (e_hi, o_hi) = x_hi.exp_x_minus_1_prec_round_ref(prec, rm);
321 if o_lo == o_hi && e_lo == e_hi {
322 return (e_lo, o_lo);
323 }
324 working_prec += increment;
325 increment = working_prec >> 1;
326 }
327}
328
329impl Float {
330 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the specified precision
331 /// and with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is
332 /// also returned, indicating whether the rounded value is less than, equal to, or greater than
333 /// the exact value. Although `NaN`s are not comparable to any [`Float`], whenever this function
334 /// returns a `NaN` it also returns `Equal`.
335 ///
336 /// See [`RoundingMode`] for a description of the possible rounding modes.
337 ///
338 /// $$
339 /// f(x,p,m) = e^x-1+\varepsilon.
340 /// $$
341 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
342 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
343 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
344 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
345 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
346 ///
347 /// If the output has a precision, it is `prec`.
348 ///
349 /// Special cases:
350 /// - $f(\text{NaN},p,m)=\text{NaN}$
351 /// - $f(\infty,p,m)=\infty$
352 /// - $f(-\infty,p,m)=-1$
353 /// - $f(\pm0.0,p,m)=\pm0.0$
354 ///
355 /// Overflow and underflow:
356 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
357 /// returned instead.
358 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
359 /// returned instead.
360 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
361 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
362 /// instead.
363 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
364 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
365 /// instead.
366 ///
367 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
368 ///
369 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_prec`] instead.
370 /// If you know that your target precision is the precision of the input, consider using
371 /// [`Float::exp_x_minus_1_round`] instead. If both of these things are true, consider using
372 /// [`Float::exp_x_minus_1`] instead.
373 ///
374 /// # Worst-case complexity
375 /// $T(n) = O(n^{3/2} \log n \log\log n)$
376 ///
377 /// $M(n) = O(n \log n)$
378 ///
379 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
380 ///
381 /// # Panics
382 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
383 /// with the given precision. (The result cannot be represented exactly whenever the input is
384 /// finite and nonzero.)
385 ///
386 /// # Examples
387 /// ```
388 /// use malachite_base::rounding_modes::RoundingMode::*;
389 /// use malachite_float::Float;
390 /// use std::cmp::Ordering::*;
391 ///
392 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
393 /// .0
394 /// .exp_x_minus_1_prec_round(20, Floor);
395 /// assert_eq!(e.to_string(), "1.7182808");
396 /// assert_eq!(o, Less);
397 ///
398 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
399 /// .0
400 /// .exp_x_minus_1_prec_round(20, Ceiling);
401 /// assert_eq!(e.to_string(), "1.7182827");
402 /// assert_eq!(o, Greater);
403 /// ```
404 #[inline]
405 pub fn exp_x_minus_1_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
406 self.exp_x_minus_1_prec_round_ref(prec, rm)
407 }
408
409 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the specified precision
410 /// and with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`]
411 /// is also returned, indicating whether the rounded value is less than, equal to, or greater
412 /// than the exact value. Although `NaN`s are not comparable to any [`Float`], whenever this
413 /// function returns a `NaN` it also returns `Equal`.
414 ///
415 /// See [`RoundingMode`] for a description of the possible rounding modes.
416 ///
417 /// $$
418 /// f(x,p,m) = e^x-1+\varepsilon.
419 /// $$
420 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
421 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
422 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
423 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
424 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
425 ///
426 /// If the output has a precision, it is `prec`.
427 ///
428 /// Special cases:
429 /// - $f(\text{NaN},p,m)=\text{NaN}$
430 /// - $f(\infty,p,m)=\infty$
431 /// - $f(-\infty,p,m)=-1$
432 /// - $f(\pm0.0,p,m)=\pm0.0$
433 ///
434 /// Overflow and underflow:
435 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
436 /// returned instead.
437 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
438 /// returned instead.
439 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
440 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
441 /// instead.
442 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
443 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
444 /// instead.
445 ///
446 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
447 ///
448 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_prec_ref`]
449 /// instead. If you know that your target precision is the precision of the input, consider
450 /// using [`Float::exp_x_minus_1_round_ref`] instead. If both of these things are true, consider
451 /// using `(&Float).exp_x_minus_1()` instead.
452 ///
453 /// # Worst-case complexity
454 /// $T(n) = O(n^{3/2} \log n \log\log n)$
455 ///
456 /// $M(n) = O(n \log n)$
457 ///
458 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
459 ///
460 /// # Panics
461 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
462 /// with the given precision. (The result cannot be represented exactly whenever the input is
463 /// finite and nonzero.)
464 ///
465 /// # Examples
466 /// ```
467 /// use malachite_base::rounding_modes::RoundingMode::*;
468 /// use malachite_float::Float;
469 /// use std::cmp::Ordering::*;
470 ///
471 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
472 /// .0
473 /// .exp_x_minus_1_prec_round_ref(20, Floor);
474 /// assert_eq!(e.to_string(), "1.7182808");
475 /// assert_eq!(o, Less);
476 ///
477 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
478 /// .0
479 /// .exp_x_minus_1_prec_round_ref(20, Ceiling);
480 /// assert_eq!(e.to_string(), "1.7182827");
481 /// assert_eq!(o, Greater);
482 /// ```
483 #[inline]
484 pub fn exp_x_minus_1_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
485 assert_ne!(prec, 0);
486 match self {
487 Self(NaN) => (float_nan!(), Equal),
488 float_infinity!() => (float_infinity!(), Equal),
489 // expm1(-inf) = -1
490 Self(Infinity { sign: false }) => (Self::from_signed_prec(-1i32, prec).0, Equal),
491 // expm1(±0) = ±0
492 Self(Zero { sign }) => (Self(Zero { sign: *sign }), Equal),
493 _ => exp_x_minus_1_prec_round_normal(self, prec, rm),
494 }
495 }
496
497 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the nearest value of the
498 /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
499 /// indicating whether the rounded value is less than, equal to, or greater than the exact
500 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
501 /// `NaN` it also returns `Equal`.
502 ///
503 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
504 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
505 /// the `Nearest` rounding mode.
506 ///
507 /// $$
508 /// f(x,p) = e^x-1+\varepsilon.
509 /// $$
510 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
511 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
512 /// |e^x-1|\rfloor-p}$.
513 ///
514 /// If the output has a precision, it is `prec`.
515 ///
516 /// Special cases:
517 /// - $f(\text{NaN},p)=\text{NaN}$
518 /// - $f(\infty,p)=\infty$
519 /// - $f(-\infty,p)=-1$
520 /// - $f(\pm0.0,p)=\pm0.0$
521 ///
522 /// Overflow and underflow:
523 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
524 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
525 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
526 ///
527 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
528 ///
529 /// If you want to use a rounding mode other than `Nearest`, consider using
530 /// [`Float::exp_x_minus_1_prec_round`] instead. If you know that your target precision is the
531 /// precision of the input, consider using [`Float::exp_x_minus_1`] instead.
532 ///
533 /// # Worst-case complexity
534 /// $T(n) = O(n^{3/2} \log n \log\log n)$
535 ///
536 /// $M(n) = O(n \log n)$
537 ///
538 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
539 ///
540 /// # Panics
541 /// Panics if `prec` is zero.
542 ///
543 /// # Examples
544 /// ```
545 /// use malachite_float::Float;
546 /// use std::cmp::Ordering::*;
547 ///
548 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
549 /// .0
550 /// .exp_x_minus_1_prec(20);
551 /// assert_eq!(e.to_string(), "1.7182827");
552 /// assert_eq!(o, Greater);
553 /// ```
554 #[inline]
555 pub fn exp_x_minus_1_prec(self, prec: u64) -> (Self, Ordering) {
556 self.exp_x_minus_1_prec_round(prec, Nearest)
557 }
558
559 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the nearest value of the
560 /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
561 /// indicating whether the rounded value is less than, equal to, or greater than the exact
562 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
563 /// `NaN` it also returns `Equal`.
564 ///
565 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
566 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
567 /// the `Nearest` rounding mode.
568 ///
569 /// $$
570 /// f(x,p) = e^x-1+\varepsilon.
571 /// $$
572 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
573 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
574 /// |e^x-1|\rfloor-p}$.
575 ///
576 /// If the output has a precision, it is `prec`.
577 ///
578 /// Special cases:
579 /// - $f(\text{NaN},p)=\text{NaN}$
580 /// - $f(\infty,p)=\infty$
581 /// - $f(-\infty,p)=-1$
582 /// - $f(\pm0.0,p)=\pm0.0$
583 ///
584 /// Overflow and underflow:
585 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
586 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
587 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
588 ///
589 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
590 ///
591 /// If you want to use a rounding mode other than `Nearest`, consider using
592 /// [`Float::exp_x_minus_1_prec_round_ref`] instead. If you know that your target precision is
593 /// the precision of the input, consider using `(&Float).exp_x_minus_1()` instead.
594 ///
595 /// # Worst-case complexity
596 /// $T(n) = O(n^{3/2} \log n \log\log n)$
597 ///
598 /// $M(n) = O(n \log n)$
599 ///
600 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
601 ///
602 /// # Panics
603 /// Panics if `prec` is zero.
604 ///
605 /// # Examples
606 /// ```
607 /// use malachite_float::Float;
608 /// use std::cmp::Ordering::*;
609 ///
610 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
611 /// .0
612 /// .exp_x_minus_1_prec_ref(20);
613 /// assert_eq!(e.to_string(), "1.7182827");
614 /// assert_eq!(o, Greater);
615 /// ```
616 #[inline]
617 pub fn exp_x_minus_1_prec_ref(&self, prec: u64) -> (Self, Ordering) {
618 self.exp_x_minus_1_prec_round_ref(prec, Nearest)
619 }
620
621 #[allow(clippy::needless_pass_by_value)]
622 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
623 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
624 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
625 /// rounded value is less than, equal to, or greater than the exact value.
626 ///
627 /// See [`RoundingMode`] for a description of the possible rounding modes.
628 ///
629 /// $$
630 /// f(x,p,m) = e^x-1+\varepsilon.
631 /// $$
632 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
633 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
634 ///
635 /// These bounds do not apply when the result overflows or underflows; see below.
636 ///
637 /// The output has precision `prec`.
638 ///
639 /// Special cases:
640 /// - $f(0,p,m)=0$.
641 ///
642 /// Overflow and underflow:
643 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
644 /// returned instead.
645 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
646 /// returned instead.
647 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
648 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
649 /// instead.
650 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
651 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
652 /// instead.
653 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
654 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
655 /// instead.
656 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
657 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
658 /// instead.
659 ///
660 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
661 /// $-1$.
662 ///
663 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_rational_prec`]
664 /// instead.
665 ///
666 /// # Worst-case complexity
667 /// $T(n) = O(n^{3/2} \log n \log\log n)$
668 ///
669 /// $M(n) = O(n \log n)$
670 ///
671 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
672 ///
673 /// # Panics
674 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
675 /// with the given precision (which is the case for every nonzero input).
676 ///
677 /// # Examples
678 /// ```
679 /// use malachite_base::rounding_modes::RoundingMode::*;
680 /// use malachite_float::Float;
681 /// use malachite_q::Rational;
682 /// use std::cmp::Ordering::*;
683 ///
684 /// let (e, o) =
685 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
686 /// assert_eq!(e.to_string(), "0.812");
687 /// assert_eq!(o, Less);
688 ///
689 /// let (e, o) =
690 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
691 /// assert_eq!(e.to_string(), "0.844");
692 /// assert_eq!(o, Greater);
693 ///
694 /// let (e, o) =
695 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
696 /// assert_eq!(e.to_string(), "0.82211876");
697 /// assert_eq!(o, Less);
698 ///
699 /// let (e, o) =
700 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
701 /// assert_eq!(e.to_string(), "0.82211971");
702 /// assert_eq!(o, Greater);
703 /// ```
704 #[inline]
705 pub fn exp_x_minus_1_rational_prec_round(
706 x: Rational,
707 prec: u64,
708 rm: RoundingMode,
709 ) -> (Self, Ordering) {
710 Self::exp_x_minus_1_rational_prec_round_ref(&x, prec, rm)
711 }
712
713 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
714 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
715 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
716 /// rounded value is less than, equal to, or greater than the exact value.
717 ///
718 /// See [`RoundingMode`] for a description of the possible rounding modes.
719 ///
720 /// $$
721 /// f(x,p,m) = e^x-1+\varepsilon.
722 /// $$
723 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
724 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
725 ///
726 /// These bounds do not apply when the result overflows or underflows; see below.
727 ///
728 /// The output has precision `prec`.
729 ///
730 /// Special cases:
731 /// - $f(0,p,m)=0$.
732 ///
733 /// Overflow and underflow:
734 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
735 /// returned instead.
736 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
737 /// returned instead.
738 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
739 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
740 /// instead.
741 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
742 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
743 /// instead.
744 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
745 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
746 /// instead.
747 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
748 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
749 /// instead.
750 ///
751 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
752 /// $-1$.
753 ///
754 /// If you know you'll be using `Nearest`, consider using
755 /// [`Float::exp_x_minus_1_rational_prec_ref`] instead.
756 ///
757 /// # Worst-case complexity
758 /// $T(n) = O(n^{3/2} \log n \log\log n)$
759 ///
760 /// $M(n) = O(n \log n)$
761 ///
762 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
763 ///
764 /// # Panics
765 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
766 /// with the given precision (which is the case for every nonzero input).
767 ///
768 /// # Examples
769 /// ```
770 /// use malachite_base::rounding_modes::RoundingMode::*;
771 /// use malachite_float::Float;
772 /// use malachite_q::Rational;
773 /// use std::cmp::Ordering::*;
774 ///
775 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
776 /// &Rational::from_unsigneds(3u8, 5),
777 /// 5,
778 /// Floor,
779 /// );
780 /// assert_eq!(e.to_string(), "0.812");
781 /// assert_eq!(o, Less);
782 ///
783 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
784 /// &Rational::from_unsigneds(3u8, 5),
785 /// 5,
786 /// Ceiling,
787 /// );
788 /// assert_eq!(e.to_string(), "0.844");
789 /// assert_eq!(o, Greater);
790 ///
791 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
792 /// &Rational::from_unsigneds(3u8, 5),
793 /// 20,
794 /// Floor,
795 /// );
796 /// assert_eq!(e.to_string(), "0.82211876");
797 /// assert_eq!(o, Less);
798 ///
799 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
800 /// &Rational::from_unsigneds(3u8, 5),
801 /// 20,
802 /// Ceiling,
803 /// );
804 /// assert_eq!(e.to_string(), "0.82211971");
805 /// assert_eq!(o, Greater);
806 /// ```
807 pub fn exp_x_minus_1_rational_prec_round_ref(
808 x: &Rational,
809 prec: u64,
810 rm: RoundingMode,
811 ) -> (Self, Ordering) {
812 assert_ne!(prec, 0);
813 if *x == 0u32 {
814 // expm1(0) = 0, exactly.
815 return (float_zero!(), Equal);
816 }
817 exp_x_minus_1_rational_helper(x, prec, rm)
818 }
819
820 #[allow(clippy::needless_pass_by_value)]
821 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
822 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
823 /// by value. An [`Ordering`] is also returned, indicating whether the rounded value is less
824 /// than, equal to, or greater than the exact value.
825 ///
826 /// If the value is equidistant from two [`Float`]s with the specified precision, the [`Float`]
827 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
828 /// the `Nearest` rounding mode.
829 ///
830 /// $$
831 /// f(x,p) = e^x-1+\varepsilon,
832 /// $$
833 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$ (unless the result overflows
834 /// or underflows; see below).
835 ///
836 /// The output has precision `prec`.
837 ///
838 /// Special cases:
839 /// - $f(0,p)=0$.
840 ///
841 /// Overflow and underflow:
842 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
843 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
844 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
845 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
846 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
847 ///
848 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
849 /// $-1$.
850 ///
851 /// If you want to use a rounding mode other than `Nearest`, consider using
852 /// [`Float::exp_x_minus_1_rational_prec_round`] instead.
853 ///
854 /// # Worst-case complexity
855 /// $T(n) = O(n^{3/2} \log n \log\log n)$
856 ///
857 /// $M(n) = O(n \log n)$
858 ///
859 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
860 ///
861 /// # Panics
862 /// Panics if `prec` is zero.
863 ///
864 /// # Examples
865 /// ```
866 /// use malachite_float::Float;
867 /// use malachite_q::Rational;
868 /// use std::cmp::Ordering::*;
869 ///
870 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
871 /// assert_eq!(e.to_string(), "0.812");
872 /// assert_eq!(o, Less);
873 ///
874 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
875 /// assert_eq!(e.to_string(), "0.82211876");
876 /// assert_eq!(o, Less);
877 ///
878 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_signeds(-3i8, 5), 10);
879 /// assert_eq!(e.to_string(), "-0.45117");
880 /// assert_eq!(o, Greater);
881 ///
882 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from(0), 10);
883 /// assert_eq!(e.to_string(), "0.0");
884 /// assert_eq!(o, Equal);
885 /// ```
886 #[inline]
887 pub fn exp_x_minus_1_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
888 Self::exp_x_minus_1_rational_prec_round_ref(&x, prec, Nearest)
889 }
890
891 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
892 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
893 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded value is less
894 /// than, equal to, or greater than the exact value.
895 ///
896 /// If the value is equidistant from two [`Float`]s with the specified precision, the [`Float`]
897 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
898 /// the `Nearest` rounding mode.
899 ///
900 /// $$
901 /// f(x,p) = e^x-1+\varepsilon,
902 /// $$
903 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$ (unless the result overflows
904 /// or underflows; see below).
905 ///
906 /// The output has precision `prec`.
907 ///
908 /// Special cases:
909 /// - $f(0,p)=0$.
910 ///
911 /// Overflow and underflow:
912 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
913 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
914 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
915 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
916 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
917 ///
918 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
919 /// $-1$.
920 ///
921 /// If you want to use a rounding mode other than `Nearest`, consider using
922 /// [`Float::exp_x_minus_1_rational_prec_round_ref`] instead.
923 ///
924 /// # Worst-case complexity
925 /// $T(n) = O(n^{3/2} \log n \log\log n)$
926 ///
927 /// $M(n) = O(n \log n)$
928 ///
929 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
930 ///
931 /// # Panics
932 /// Panics if `prec` is zero.
933 ///
934 /// # Examples
935 /// ```
936 /// use malachite_float::Float;
937 /// use malachite_q::Rational;
938 /// use std::cmp::Ordering::*;
939 ///
940 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
941 /// assert_eq!(e.to_string(), "0.812");
942 /// assert_eq!(o, Less);
943 ///
944 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
945 /// assert_eq!(e.to_string(), "0.82211876");
946 /// assert_eq!(o, Less);
947 ///
948 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_signeds(-3i8, 5), 10);
949 /// assert_eq!(e.to_string(), "-0.45117");
950 /// assert_eq!(o, Greater);
951 ///
952 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from(0), 10);
953 /// assert_eq!(e.to_string(), "0.0");
954 /// assert_eq!(o, Equal);
955 /// ```
956 #[inline]
957 pub fn exp_x_minus_1_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
958 Self::exp_x_minus_1_rational_prec_round_ref(x, prec, Nearest)
959 }
960
961 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result with the specified rounding
962 /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
963 /// the rounded value is less than, equal to, or greater than the exact value. Although `NaN`s
964 /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
965 /// `Equal`.
966 ///
967 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
968 /// description of the possible rounding modes.
969 ///
970 /// $$
971 /// f(x,m) = e^x-1+\varepsilon.
972 /// $$
973 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
974 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
975 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
976 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
977 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
978 ///
979 /// If the output has a precision, it is the precision of the input.
980 ///
981 /// Special cases:
982 /// - $f(\text{NaN},m)=\text{NaN}$
983 /// - $f(\infty,m)=\infty$
984 /// - $f(-\infty,m)=-1$
985 /// - $f(\pm0.0,m)=\pm0.0$
986 ///
987 /// Overflow and underflow:
988 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
989 /// returned instead.
990 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
991 /// returned instead.
992 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
993 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned instead.
994 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
995 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
996 /// instead.
997 ///
998 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
999 ///
1000 /// If you want to specify an output precision, consider using
1001 /// [`Float::exp_x_minus_1_prec_round`] instead. If you know you'll be using the `Nearest`
1002 /// rounding mode, consider using [`Float::exp_x_minus_1`] instead.
1003 ///
1004 /// # Worst-case complexity
1005 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1006 ///
1007 /// $M(n) = O(n \log n)$
1008 ///
1009 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1010 ///
1011 /// # Panics
1012 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1013 /// precision. (The result cannot be represented exactly whenever the input is finite and
1014 /// nonzero.)
1015 ///
1016 /// # Examples
1017 /// ```
1018 /// use malachite_base::rounding_modes::RoundingMode::*;
1019 /// use malachite_float::Float;
1020 /// use std::cmp::Ordering::*;
1021 ///
1022 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1023 /// .0
1024 /// .exp_x_minus_1_round(Floor);
1025 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713512");
1026 /// assert_eq!(o, Less);
1027 ///
1028 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1029 /// .0
1030 /// .exp_x_minus_1_round(Ceiling);
1031 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713528");
1032 /// assert_eq!(o, Greater);
1033 /// ```
1034 #[inline]
1035 pub fn exp_x_minus_1_round(self, rm: RoundingMode) -> (Self, Ordering) {
1036 let prec = self.significant_bits();
1037 self.exp_x_minus_1_prec_round(prec, rm)
1038 }
1039
1040 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result with the specified rounding
1041 /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
1042 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
1043 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1044 /// returns `Equal`.
1045 ///
1046 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1047 /// description of the possible rounding modes.
1048 ///
1049 /// $$
1050 /// f(x,m) = e^x-1+\varepsilon.
1051 /// $$
1052 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1053 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1054 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
1055 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1056 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1057 ///
1058 /// If the output has a precision, it is the precision of the input.
1059 ///
1060 /// Special cases:
1061 /// - $f(\text{NaN},m)=\text{NaN}$
1062 /// - $f(\infty,m)=\infty$
1063 /// - $f(-\infty,m)=-1$
1064 /// - $f(\pm0.0,m)=\pm0.0$
1065 ///
1066 /// Overflow and underflow:
1067 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1068 /// returned instead.
1069 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1070 /// returned instead.
1071 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1072 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned instead.
1073 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
1074 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1075 /// instead.
1076 ///
1077 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1078 ///
1079 /// If you want to specify an output precision, consider using
1080 /// [`Float::exp_x_minus_1_prec_round_ref`] instead. If you know you'll be using the `Nearest`
1081 /// rounding mode, consider using `(&Float).exp_x_minus_1()` instead.
1082 ///
1083 /// # Worst-case complexity
1084 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1085 ///
1086 /// $M(n) = O(n \log n)$
1087 ///
1088 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1089 ///
1090 /// # Panics
1091 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1092 /// precision. (The result cannot be represented exactly whenever the input is finite and
1093 /// nonzero.)
1094 ///
1095 /// # Examples
1096 /// ```
1097 /// use malachite_base::rounding_modes::RoundingMode::*;
1098 /// use malachite_float::Float;
1099 /// use std::cmp::Ordering::*;
1100 ///
1101 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1102 /// .0
1103 /// .exp_x_minus_1_round_ref(Floor);
1104 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713512");
1105 /// assert_eq!(o, Less);
1106 ///
1107 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1108 /// .0
1109 /// .exp_x_minus_1_round_ref(Ceiling);
1110 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713528");
1111 /// assert_eq!(o, Greater);
1112 /// ```
1113 #[inline]
1114 pub fn exp_x_minus_1_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1115 self.exp_x_minus_1_prec_round_ref(self.significant_bits(), rm)
1116 }
1117
1118 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result to the specified
1119 /// precision and with the specified rounding mode. An [`Ordering`] is returned, indicating
1120 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
1121 /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
1122 /// `NaN` it also returns `Equal`.
1123 ///
1124 /// See [`RoundingMode`] for a description of the possible rounding modes.
1125 ///
1126 /// $$
1127 /// x \gets e^x-1+\varepsilon.
1128 /// $$
1129 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1130 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1131 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
1132 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1133 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
1134 ///
1135 /// If the output has a precision, it is `prec`.
1136 ///
1137 /// See the [`Float::exp_x_minus_1_prec_round`] documentation for information on special cases.
1138 ///
1139 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_prec_assign`]
1140 /// instead. If you know that your target precision is the precision of the input, consider
1141 /// using [`Float::exp_x_minus_1_round_assign`] instead. If both of these things are true,
1142 /// consider using [`Float::exp_x_minus_1_assign`] instead.
1143 ///
1144 /// # Worst-case complexity
1145 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1146 ///
1147 /// $M(n) = O(n \log n)$
1148 ///
1149 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1150 ///
1151 /// # Panics
1152 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1153 /// with the given precision. (The result cannot be represented exactly whenever the input is
1154 /// finite and nonzero.)
1155 ///
1156 /// # Examples
1157 /// ```
1158 /// use malachite_base::rounding_modes::RoundingMode::*;
1159 /// use malachite_float::Float;
1160 /// use std::cmp::Ordering::*;
1161 ///
1162 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1163 /// assert_eq!(x.exp_x_minus_1_prec_round_assign(20, Floor), Less);
1164 /// assert_eq!(x.to_string(), "1.7182808");
1165 ///
1166 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1167 /// assert_eq!(x.exp_x_minus_1_prec_round_assign(20, Ceiling), Greater);
1168 /// assert_eq!(x.to_string(), "1.7182827");
1169 /// ```
1170 #[inline]
1171 pub fn exp_x_minus_1_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1172 let (result, o) = core::mem::take(self).exp_x_minus_1_prec_round(prec, rm);
1173 *self = result;
1174 o
1175 }
1176
1177 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result to the nearest
1178 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
1179 /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
1180 /// not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
1181 /// returns `Equal`.
1182 ///
1183 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1184 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1185 /// the `Nearest` rounding mode.
1186 ///
1187 /// $$
1188 /// x \gets e^x-1+\varepsilon.
1189 /// $$
1190 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1191 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1192 /// |e^x-1|\rfloor-p}$.
1193 ///
1194 /// If the output has a precision, it is `prec`.
1195 ///
1196 /// See the [`Float::exp_x_minus_1_prec`] documentation for information on special cases.
1197 ///
1198 /// If you want to use a rounding mode other than `Nearest`, consider using
1199 /// [`Float::exp_x_minus_1_prec_round_assign`] instead. If you know that your target precision
1200 /// is the precision of the input, consider using [`Float::exp_x_minus_1_assign`] instead.
1201 ///
1202 /// # Worst-case complexity
1203 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1204 ///
1205 /// $M(n) = O(n \log n)$
1206 ///
1207 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1208 ///
1209 /// # Panics
1210 /// Panics if `prec` is zero.
1211 ///
1212 /// # Examples
1213 /// ```
1214 /// use malachite_float::Float;
1215 /// use std::cmp::Ordering::*;
1216 ///
1217 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1218 /// assert_eq!(x.exp_x_minus_1_prec_assign(20), Greater);
1219 /// assert_eq!(x.to_string(), "1.7182827");
1220 /// ```
1221 #[inline]
1222 pub fn exp_x_minus_1_prec_assign(&mut self, prec: u64) -> Ordering {
1223 self.exp_x_minus_1_prec_round_assign(prec, Nearest)
1224 }
1225
1226 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result with the specified
1227 /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded value is less
1228 /// than, equal to, or greater than the exact value. Although `NaN`s are not comparable to any
1229 /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
1230 ///
1231 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1232 /// description of the possible rounding modes.
1233 ///
1234 /// $$
1235 /// x \gets e^x-1+\varepsilon.
1236 /// $$
1237 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1238 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1239 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
1240 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1241 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1242 ///
1243 /// If the output has a precision, it is the precision of the input.
1244 ///
1245 /// See the [`Float::exp_x_minus_1_round`] documentation for information on special cases.
1246 ///
1247 /// If you want to specify an output precision, consider using
1248 /// [`Float::exp_x_minus_1_prec_round_assign`] instead. If you know you'll be using the
1249 /// `Nearest` rounding mode, consider using [`Float::exp_x_minus_1_assign`] instead.
1250 ///
1251 /// # Worst-case complexity
1252 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1253 ///
1254 /// $M(n) = O(n \log n)$
1255 ///
1256 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1257 ///
1258 /// # Panics
1259 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1260 /// precision. (The result cannot be represented exactly whenever the input is finite and
1261 /// nonzero.)
1262 ///
1263 /// # Examples
1264 /// ```
1265 /// use malachite_base::rounding_modes::RoundingMode::*;
1266 /// use malachite_float::Float;
1267 /// use std::cmp::Ordering::*;
1268 ///
1269 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1270 /// assert_eq!(x.exp_x_minus_1_round_assign(Floor), Less);
1271 /// assert_eq!(x.to_string(), "1.7182818284590452353602874713512");
1272 ///
1273 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1274 /// assert_eq!(x.exp_x_minus_1_round_assign(Ceiling), Greater);
1275 /// assert_eq!(x.to_string(), "1.7182818284590452353602874713528");
1276 /// ```
1277 #[inline]
1278 pub fn exp_x_minus_1_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1279 let prec = self.significant_bits();
1280 self.exp_x_minus_1_prec_round_assign(prec, rm)
1281 }
1282}
1283
1284impl ExpXMinus1 for Float {
1285 type Output = Self;
1286
1287 /// Computes $e^x-1$, where $x$ is a [`Float`], taking the [`Float`] by value.
1288 ///
1289 /// If the output has a precision, it is the precision of the input. If the result is
1290 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1291 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1292 /// rounding mode.
1293 ///
1294 /// $$
1295 /// f(x) = e^x-1+\varepsilon.
1296 /// $$
1297 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1298 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1299 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1300 ///
1301 /// Special cases:
1302 /// - $f(\text{NaN})=\text{NaN}$
1303 /// - $f(\infty)=\infty$
1304 /// - $f(-\infty)=-1$
1305 /// - $f(\pm0.0)=\pm0.0$
1306 ///
1307 /// Overflow and underflow:
1308 /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1309 /// - If $-2^{-2^{30}-1}\leq f(x)<0$, $-0.0$ is returned instead.
1310 /// - If $-2^{-2^{30}}<f(x)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1311 ///
1312 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1313 ///
1314 /// If you want to use a rounding mode other than `Nearest`, consider using
1315 /// [`Float::exp_x_minus_1_round`] instead. If you want to specify the output precision,
1316 /// consider using [`Float::exp_x_minus_1_prec`]. If you want both of these things, consider
1317 /// using [`Float::exp_x_minus_1_prec_round`].
1318 ///
1319 /// # Worst-case complexity
1320 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1321 ///
1322 /// $M(n) = O(n \log n)$
1323 ///
1324 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1325 ///
1326 /// # Examples
1327 /// ```
1328 /// use malachite_base::num::arithmetic::traits::ExpXMinus1;
1329 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1330 /// use malachite_float::Float;
1331 ///
1332 /// assert!(Float::NAN.exp_x_minus_1().is_nan());
1333 /// assert_eq!(Float::INFINITY.exp_x_minus_1(), Float::INFINITY);
1334 /// assert_eq!(Float::NEGATIVE_INFINITY.exp_x_minus_1().to_string(), "-1.0");
1335 /// assert_eq!(Float::ONE.exp_x_minus_1().to_string(), "2.0");
1336 /// ```
1337 #[inline]
1338 fn exp_x_minus_1(self) -> Self {
1339 let prec = self.significant_bits();
1340 self.exp_x_minus_1_prec(prec).0
1341 }
1342}
1343
1344impl ExpXMinus1 for &Float {
1345 type Output = Float;
1346
1347 /// Computes $e^x-1$, where $x$ is a [`Float`], taking the [`Float`] by reference.
1348 ///
1349 /// If the output has a precision, it is the precision of the input. If the result is
1350 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1351 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1352 /// rounding mode.
1353 ///
1354 /// $$
1355 /// f(x) = e^x-1+\varepsilon.
1356 /// $$
1357 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1358 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1359 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1360 ///
1361 /// Special cases:
1362 /// - $f(\text{NaN})=\text{NaN}$
1363 /// - $f(\infty)=\infty$
1364 /// - $f(-\infty)=-1$
1365 /// - $f(\pm0.0)=\pm0.0$
1366 ///
1367 /// Overflow and underflow:
1368 /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1369 /// - If $-2^{-2^{30}-1}\leq f(x)<0$, $-0.0$ is returned instead.
1370 /// - If $-2^{-2^{30}}<f(x)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1371 ///
1372 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1373 ///
1374 /// If you want to use a rounding mode other than `Nearest`, consider using
1375 /// [`Float::exp_x_minus_1_round_ref`] instead. If you want to specify the output precision,
1376 /// consider using [`Float::exp_x_minus_1_prec_ref`]. If you want both of these things, consider
1377 /// using [`Float::exp_x_minus_1_prec_round_ref`].
1378 ///
1379 /// # Worst-case complexity
1380 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1381 ///
1382 /// $M(n) = O(n \log n)$
1383 ///
1384 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1385 ///
1386 /// # Examples
1387 /// ```
1388 /// use malachite_base::num::arithmetic::traits::ExpXMinus1;
1389 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1390 /// use malachite_float::Float;
1391 ///
1392 /// assert!((&Float::NAN).exp_x_minus_1().is_nan());
1393 /// assert_eq!((&Float::INFINITY).exp_x_minus_1(), Float::INFINITY);
1394 /// assert_eq!(
1395 /// (&Float::NEGATIVE_INFINITY).exp_x_minus_1().to_string(),
1396 /// "-1.0"
1397 /// );
1398 /// assert_eq!((&Float::ONE).exp_x_minus_1().to_string(), "2.0");
1399 /// ```
1400 #[inline]
1401 fn exp_x_minus_1(self) -> Float {
1402 self.exp_x_minus_1_prec_round_ref(self.significant_bits(), Nearest)
1403 .0
1404 }
1405}
1406
1407impl ExpXMinus1Assign for Float {
1408 /// Computes $e^x-1$, where $x$ is a [`Float`], in place.
1409 ///
1410 /// If the output has a precision, it is the precision of the input. If the result is
1411 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1412 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1413 /// rounding mode.
1414 ///
1415 /// $$
1416 /// x \gets e^x-1+\varepsilon.
1417 /// $$
1418 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1419 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1420 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1421 ///
1422 /// See the [`Float::exp_x_minus_1`] documentation for information on special cases.
1423 ///
1424 /// If you want to use a rounding mode other than `Nearest`, consider using
1425 /// [`Float::exp_x_minus_1_round_assign`] instead. If you want to specify the output precision,
1426 /// consider using [`Float::exp_x_minus_1_prec_assign`]. If you want both of these things,
1427 /// consider using [`Float::exp_x_minus_1_prec_round_assign`].
1428 ///
1429 /// # Worst-case complexity
1430 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1431 ///
1432 /// $M(n) = O(n \log n)$
1433 ///
1434 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1435 ///
1436 /// # Examples
1437 /// ```
1438 /// use malachite_base::num::arithmetic::traits::ExpXMinus1Assign;
1439 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1440 /// use malachite_float::Float;
1441 ///
1442 /// let mut x = Float::NAN;
1443 /// x.exp_x_minus_1_assign();
1444 /// assert!(x.is_nan());
1445 ///
1446 /// let mut x = Float::INFINITY;
1447 /// x.exp_x_minus_1_assign();
1448 /// assert_eq!(x, Float::INFINITY);
1449 ///
1450 /// let mut x = Float::NEGATIVE_INFINITY;
1451 /// x.exp_x_minus_1_assign();
1452 /// assert_eq!(x.to_string(), "-1.0");
1453 ///
1454 /// let mut x = Float::ONE;
1455 /// x.exp_x_minus_1_assign();
1456 /// assert_eq!(x.to_string(), "2.0");
1457 /// ```
1458 #[inline]
1459 fn exp_x_minus_1_assign(&mut self) {
1460 let prec = self.significant_bits();
1461 self.exp_x_minus_1_prec_round_assign(prec, Nearest);
1462 }
1463}
1464
1465/// Computes $e^x-1$ for a primitive float. Using this function is more accurate than using the
1466/// primitive float `exp_m1` function (the standard library's `exp_m1` is not correctly rounded).
1467///
1468/// $$
1469/// f(x) = e^x-1+\varepsilon.
1470/// $$
1471/// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1472/// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$,
1473/// where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1474/// [`f64`], but less if the output is subnormal).
1475///
1476/// Special cases:
1477/// - $f(\text{NaN})=\text{NaN}$
1478/// - $f(\infty)=\infty$
1479/// - $f(-\infty)=-1$
1480/// - $f(\pm0.0)=\pm0.0$
1481///
1482/// If the result overflows, $\infty$ is returned, and if it underflows, $-0.0$ is returned. (A
1483/// positive result never underflows: $e^x-1>x$ for positive $x$.)
1484///
1485/// # Worst-case complexity
1486/// Constant time and additional memory.
1487///
1488/// # Examples
1489/// ```
1490/// use malachite_base::num::basic::traits::NegativeInfinity;
1491/// use malachite_base::num::float::NiceFloat;
1492/// use malachite_float::float::arithmetic::exp_x_minus_1::primitive_float_exp_x_minus_1;
1493///
1494/// assert!(primitive_float_exp_x_minus_1(f32::NAN).is_nan());
1495/// assert_eq!(
1496/// NiceFloat(primitive_float_exp_x_minus_1(f32::INFINITY)),
1497/// NiceFloat(f32::INFINITY)
1498/// );
1499/// assert_eq!(
1500/// NiceFloat(primitive_float_exp_x_minus_1(f32::NEGATIVE_INFINITY)),
1501/// NiceFloat(-1.0)
1502/// );
1503/// assert_eq!(
1504/// NiceFloat(primitive_float_exp_x_minus_1(1.0f32)),
1505/// NiceFloat(1.7182819)
1506/// );
1507/// ```
1508#[inline]
1509#[allow(clippy::type_repetition_in_bounds)]
1510pub fn primitive_float_exp_x_minus_1<T: PrimitiveFloat>(x: T) -> T
1511where
1512 Float: From<T> + PartialOrd<T>,
1513 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1514{
1515 emulate_float_to_float_fn(Float::exp_x_minus_1_prec, x)
1516}
1517
1518/// Computes $e^x-1$, where $x$ is a [`Rational`], returning the result as a primitive float.
1519///
1520/// $$
1521/// f(x) = e^x-1+\varepsilon.
1522/// $$
1523/// - If $e^x-1$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
1524/// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$,
1525/// where $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1526/// [`f64`], but less if the output is subnormal).
1527///
1528/// Special cases:
1529/// - $f(0)=0$
1530///
1531/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a small nonzero
1532/// `x` may give $\pm0.0$. Unlike $e^x$, a large negative `x` does not underflow to zero; it gives
1533/// `-1.0`.
1534///
1535/// # Worst-case complexity
1536/// Constant time and additional memory.
1537///
1538/// # Examples
1539/// ```
1540/// use malachite_base::num::basic::traits::Zero;
1541/// use malachite_base::num::float::NiceFloat;
1542/// use malachite_float::float::arithmetic::exp_x_minus_1::primitive_float_exp_x_minus_1_rational;
1543/// use malachite_q::Rational;
1544///
1545/// assert_eq!(
1546/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1547/// &Rational::ZERO
1548/// )),
1549/// NiceFloat(0.0)
1550/// );
1551/// assert_eq!(
1552/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1553/// &Rational::from_unsigneds(1u8, 3)
1554/// )),
1555/// NiceFloat(0.3956124250860895)
1556/// );
1557/// assert_eq!(
1558/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1559/// &Rational::from(10000)
1560/// )),
1561/// NiceFloat(f64::INFINITY)
1562/// );
1563/// assert_eq!(
1564/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1565/// &Rational::from(-10000)
1566/// )),
1567/// NiceFloat(-1.0)
1568/// );
1569/// ```
1570#[inline]
1571#[allow(clippy::type_repetition_in_bounds)]
1572pub fn primitive_float_exp_x_minus_1_rational<T: PrimitiveFloat>(x: &Rational) -> T
1573where
1574 Float: PartialOrd<T>,
1575 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1576{
1577 emulate_rational_to_float_fn(Float::exp_x_minus_1_rational_prec_ref, x)
1578}