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::round::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 == Float::MIN_EXPONENT_I64 {
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 Float::MAX_EXPONENT_U64,
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 Float::MAX_EXPONENT_U64
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 = Float::MAX_EXPONENT_U64;
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, m) = O(n^{3/2} \log n \log\log n + m)$
376 ///
377 /// $M(n, m) = O(n \log n + m)$
378 ///
379 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
380 /// `self.significant_bits()`.
381 ///
382 /// # Panics
383 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
384 /// with the given precision. (The result cannot be represented exactly whenever the input is
385 /// finite and nonzero.)
386 ///
387 /// # Examples
388 /// ```
389 /// use malachite_base::rounding_modes::RoundingMode::*;
390 /// use malachite_float::Float;
391 /// use std::cmp::Ordering::*;
392 ///
393 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
394 /// .0
395 /// .exp_x_minus_1_prec_round(20, Floor);
396 /// assert_eq!(e.to_string(), "1.7182808");
397 /// assert_eq!(o, Less);
398 ///
399 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
400 /// .0
401 /// .exp_x_minus_1_prec_round(20, Ceiling);
402 /// assert_eq!(e.to_string(), "1.7182827");
403 /// assert_eq!(o, Greater);
404 /// ```
405 #[inline]
406 pub fn exp_x_minus_1_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
407 self.exp_x_minus_1_prec_round_ref(prec, rm)
408 }
409
410 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the specified precision
411 /// and with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`]
412 /// is also returned, indicating whether the rounded value is less than, equal to, or greater
413 /// than the exact value. Although `NaN`s are not comparable to any [`Float`], whenever this
414 /// function returns a `NaN` it also returns `Equal`.
415 ///
416 /// See [`RoundingMode`] for a description of the possible rounding modes.
417 ///
418 /// $$
419 /// f(x,p,m) = e^x-1+\varepsilon.
420 /// $$
421 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
422 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
423 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
424 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
425 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
426 ///
427 /// If the output has a precision, it is `prec`.
428 ///
429 /// Special cases:
430 /// - $f(\text{NaN},p,m)=\text{NaN}$
431 /// - $f(\infty,p,m)=\infty$
432 /// - $f(-\infty,p,m)=-1$
433 /// - $f(\pm0.0,p,m)=\pm0.0$
434 ///
435 /// Overflow and underflow:
436 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
437 /// returned instead.
438 /// - 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
439 /// returned instead.
440 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
441 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
442 /// instead.
443 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
444 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
445 /// instead.
446 ///
447 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
448 ///
449 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_prec_ref`]
450 /// instead. If you know that your target precision is the precision of the input, consider
451 /// using [`Float::exp_x_minus_1_round_ref`] instead. If both of these things are true, consider
452 /// using `(&Float).exp_x_minus_1()` instead.
453 ///
454 /// # Worst-case complexity
455 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
456 ///
457 /// $M(n, m) = O(n \log n + m)$
458 ///
459 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
460 /// `self.significant_bits()`.
461 ///
462 /// # Panics
463 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
464 /// with the given precision. (The result cannot be represented exactly whenever the input is
465 /// finite and nonzero.)
466 ///
467 /// # Examples
468 /// ```
469 /// use malachite_base::rounding_modes::RoundingMode::*;
470 /// use malachite_float::Float;
471 /// use std::cmp::Ordering::*;
472 ///
473 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
474 /// .0
475 /// .exp_x_minus_1_prec_round_ref(20, Floor);
476 /// assert_eq!(e.to_string(), "1.7182808");
477 /// assert_eq!(o, Less);
478 ///
479 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
480 /// .0
481 /// .exp_x_minus_1_prec_round_ref(20, Ceiling);
482 /// assert_eq!(e.to_string(), "1.7182827");
483 /// assert_eq!(o, Greater);
484 /// ```
485 #[inline]
486 pub fn exp_x_minus_1_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
487 assert_ne!(prec, 0);
488 match self {
489 Self(NaN) => (float_nan!(), Equal),
490 float_infinity!() => (float_infinity!(), Equal),
491 // expm1(-inf) = -1
492 Self(Infinity { sign: false }) => (Self::from_signed_prec(-1i32, prec).0, Equal),
493 // expm1(±0) = ±0
494 Self(Zero { sign }) => (Self(Zero { sign: *sign }), Equal),
495 _ => exp_x_minus_1_prec_round_normal(self, prec, rm),
496 }
497 }
498
499 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the nearest value of the
500 /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
501 /// indicating whether the rounded value is less than, equal to, or greater than the exact
502 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
503 /// `NaN` it also returns `Equal`.
504 ///
505 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
506 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
507 /// the `Nearest` rounding mode.
508 ///
509 /// $$
510 /// f(x,p) = e^x-1+\varepsilon.
511 /// $$
512 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
513 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
514 /// |e^x-1|\rfloor-p}$.
515 ///
516 /// If the output has a precision, it is `prec`.
517 ///
518 /// Special cases:
519 /// - $f(\text{NaN},p)=\text{NaN}$
520 /// - $f(\infty,p)=\infty$
521 /// - $f(-\infty,p)=-1$
522 /// - $f(\pm0.0,p)=\pm0.0$
523 ///
524 /// Overflow and underflow:
525 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
526 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
527 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
528 ///
529 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
530 ///
531 /// If you want to use a rounding mode other than `Nearest`, consider using
532 /// [`Float::exp_x_minus_1_prec_round`] instead. If you know that your target precision is the
533 /// precision of the input, consider using [`Float::exp_x_minus_1`] instead.
534 ///
535 /// # Worst-case complexity
536 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
537 ///
538 /// $M(n, m) = O(n \log n + m)$
539 ///
540 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
541 /// `self.significant_bits()`.
542 ///
543 /// # Panics
544 /// Panics if `prec` is zero.
545 ///
546 /// # Examples
547 /// ```
548 /// use malachite_float::Float;
549 /// use std::cmp::Ordering::*;
550 ///
551 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
552 /// .0
553 /// .exp_x_minus_1_prec(20);
554 /// assert_eq!(e.to_string(), "1.7182827");
555 /// assert_eq!(o, Greater);
556 /// ```
557 #[inline]
558 pub fn exp_x_minus_1_prec(self, prec: u64) -> (Self, Ordering) {
559 self.exp_x_minus_1_prec_round(prec, Nearest)
560 }
561
562 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result to the nearest value of the
563 /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
564 /// indicating whether the rounded value is less than, equal to, or greater than the exact
565 /// value. Although `NaN`s are not comparable to any [`Float`], whenever this function returns a
566 /// `NaN` it also returns `Equal`.
567 ///
568 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
569 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
570 /// the `Nearest` rounding mode.
571 ///
572 /// $$
573 /// f(x,p) = e^x-1+\varepsilon.
574 /// $$
575 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
576 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
577 /// |e^x-1|\rfloor-p}$.
578 ///
579 /// If the output has a precision, it is `prec`.
580 ///
581 /// Special cases:
582 /// - $f(\text{NaN},p)=\text{NaN}$
583 /// - $f(\infty,p)=\infty$
584 /// - $f(-\infty,p)=-1$
585 /// - $f(\pm0.0,p)=\pm0.0$
586 ///
587 /// Overflow and underflow:
588 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
589 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
590 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
591 ///
592 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
593 ///
594 /// If you want to use a rounding mode other than `Nearest`, consider using
595 /// [`Float::exp_x_minus_1_prec_round_ref`] instead. If you know that your target precision is
596 /// the precision of the input, consider using `(&Float).exp_x_minus_1()` instead.
597 ///
598 /// # Worst-case complexity
599 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
600 ///
601 /// $M(n, m) = O(n \log n + m)$
602 ///
603 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
604 /// `self.significant_bits()`.
605 ///
606 /// # Panics
607 /// Panics if `prec` is zero.
608 ///
609 /// # Examples
610 /// ```
611 /// use malachite_float::Float;
612 /// use std::cmp::Ordering::*;
613 ///
614 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
615 /// .0
616 /// .exp_x_minus_1_prec_ref(20);
617 /// assert_eq!(e.to_string(), "1.7182827");
618 /// assert_eq!(o, Greater);
619 /// ```
620 #[inline]
621 pub fn exp_x_minus_1_prec_ref(&self, prec: u64) -> (Self, Ordering) {
622 self.exp_x_minus_1_prec_round_ref(prec, Nearest)
623 }
624
625 #[allow(clippy::needless_pass_by_value)]
626 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
627 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
628 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
629 /// rounded value is less than, equal to, or greater than the exact value.
630 ///
631 /// See [`RoundingMode`] for a description of the possible rounding modes.
632 ///
633 /// $$
634 /// f(x,p,m) = e^x-1+\varepsilon.
635 /// $$
636 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
637 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
638 ///
639 /// These bounds do not apply when the result overflows or underflows; see below.
640 ///
641 /// The output has precision `prec`.
642 ///
643 /// Special cases:
644 /// - $f(0,p,m)=0$.
645 ///
646 /// Overflow and underflow:
647 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
648 /// returned instead.
649 /// - 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
650 /// returned instead.
651 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
652 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
653 /// instead.
654 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
655 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
656 /// instead.
657 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
658 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
659 /// instead.
660 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
661 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
662 /// instead.
663 ///
664 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
665 /// $-1$.
666 ///
667 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_rational_prec`]
668 /// instead.
669 ///
670 /// # Worst-case complexity
671 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
672 ///
673 /// $M(n, m) = O(n \log n + m \log m)$
674 ///
675 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
676 /// `x.significant_bits()`.
677 ///
678 /// # Panics
679 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
680 /// with the given precision (which is the case for every nonzero input).
681 ///
682 /// # Examples
683 /// ```
684 /// use malachite_base::rounding_modes::RoundingMode::*;
685 /// use malachite_float::Float;
686 /// use malachite_q::Rational;
687 /// use std::cmp::Ordering::*;
688 ///
689 /// let (e, o) =
690 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
691 /// assert_eq!(e.to_string(), "0.812");
692 /// assert_eq!(o, Less);
693 ///
694 /// let (e, o) =
695 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
696 /// assert_eq!(e.to_string(), "0.844");
697 /// assert_eq!(o, Greater);
698 ///
699 /// let (e, o) =
700 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
701 /// assert_eq!(e.to_string(), "0.82211876");
702 /// assert_eq!(o, Less);
703 ///
704 /// let (e, o) =
705 /// Float::exp_x_minus_1_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
706 /// assert_eq!(e.to_string(), "0.82211971");
707 /// assert_eq!(o, Greater);
708 /// ```
709 #[inline]
710 pub fn exp_x_minus_1_rational_prec_round(
711 x: Rational,
712 prec: u64,
713 rm: RoundingMode,
714 ) -> (Self, Ordering) {
715 Self::exp_x_minus_1_rational_prec_round_ref(&x, prec, rm)
716 }
717
718 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
719 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
720 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
721 /// rounded value is less than, equal to, or greater than the exact value.
722 ///
723 /// See [`RoundingMode`] for a description of the possible rounding modes.
724 ///
725 /// $$
726 /// f(x,p,m) = e^x-1+\varepsilon.
727 /// $$
728 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
729 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
730 ///
731 /// These bounds do not apply when the result overflows or underflows; see below.
732 ///
733 /// The output has precision `prec`.
734 ///
735 /// Special cases:
736 /// - $f(0,p,m)=0$.
737 ///
738 /// Overflow and underflow:
739 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
740 /// returned instead.
741 /// - 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
742 /// returned instead.
743 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
744 /// - If $0<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
745 /// instead.
746 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
747 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
748 /// instead.
749 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
750 /// - If $-2^{-2^{30}}<f(x,p,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
751 /// instead.
752 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
753 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
754 /// instead.
755 ///
756 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
757 /// $-1$.
758 ///
759 /// If you know you'll be using `Nearest`, consider using
760 /// [`Float::exp_x_minus_1_rational_prec_ref`] instead.
761 ///
762 /// # Worst-case complexity
763 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
764 ///
765 /// $M(n, m) = O(n \log n + m \log m)$
766 ///
767 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
768 /// `x.significant_bits()`.
769 ///
770 /// # Panics
771 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
772 /// with the given precision (which is the case for every nonzero input).
773 ///
774 /// # Examples
775 /// ```
776 /// use malachite_base::rounding_modes::RoundingMode::*;
777 /// use malachite_float::Float;
778 /// use malachite_q::Rational;
779 /// use std::cmp::Ordering::*;
780 ///
781 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
782 /// &Rational::from_unsigneds(3u8, 5),
783 /// 5,
784 /// Floor,
785 /// );
786 /// assert_eq!(e.to_string(), "0.812");
787 /// assert_eq!(o, Less);
788 ///
789 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
790 /// &Rational::from_unsigneds(3u8, 5),
791 /// 5,
792 /// Ceiling,
793 /// );
794 /// assert_eq!(e.to_string(), "0.844");
795 /// assert_eq!(o, Greater);
796 ///
797 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
798 /// &Rational::from_unsigneds(3u8, 5),
799 /// 20,
800 /// Floor,
801 /// );
802 /// assert_eq!(e.to_string(), "0.82211876");
803 /// assert_eq!(o, Less);
804 ///
805 /// let (e, o) = Float::exp_x_minus_1_rational_prec_round_ref(
806 /// &Rational::from_unsigneds(3u8, 5),
807 /// 20,
808 /// Ceiling,
809 /// );
810 /// assert_eq!(e.to_string(), "0.82211971");
811 /// assert_eq!(o, Greater);
812 /// ```
813 pub fn exp_x_minus_1_rational_prec_round_ref(
814 x: &Rational,
815 prec: u64,
816 rm: RoundingMode,
817 ) -> (Self, Ordering) {
818 assert_ne!(prec, 0);
819 if *x == 0u32 {
820 // expm1(0) = 0, exactly.
821 return (float_zero!(), Equal);
822 }
823 exp_x_minus_1_rational_helper(x, prec, rm)
824 }
825
826 #[allow(clippy::needless_pass_by_value)]
827 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
828 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
829 /// by value. An [`Ordering`] is also returned, indicating whether the rounded value is less
830 /// than, equal to, or greater than the exact value.
831 ///
832 /// If the value is equidistant from two [`Float`]s with the specified precision, the [`Float`]
833 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
834 /// the `Nearest` rounding mode.
835 ///
836 /// $$
837 /// f(x,p) = e^x-1+\varepsilon,
838 /// $$
839 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$ (unless the result overflows
840 /// or underflows; see below).
841 ///
842 /// The output has precision `prec`.
843 ///
844 /// Special cases:
845 /// - $f(0,p)=0$.
846 ///
847 /// Overflow and underflow:
848 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
849 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
850 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
851 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
852 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
853 ///
854 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
855 /// $-1$.
856 ///
857 /// If you want to use a rounding mode other than `Nearest`, consider using
858 /// [`Float::exp_x_minus_1_rational_prec_round`] instead.
859 ///
860 /// # Worst-case complexity
861 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
862 ///
863 /// $M(n, m) = O(n \log n + m \log m)$
864 ///
865 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
866 /// `x.significant_bits()`.
867 ///
868 /// # Panics
869 /// Panics if `prec` is zero.
870 ///
871 /// # Examples
872 /// ```
873 /// use malachite_base::num::basic::traits::Zero;
874 /// use malachite_float::Float;
875 /// use malachite_q::Rational;
876 /// use std::cmp::Ordering::*;
877 ///
878 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
879 /// assert_eq!(e.to_string(), "0.812");
880 /// assert_eq!(o, Less);
881 ///
882 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
883 /// assert_eq!(e.to_string(), "0.82211876");
884 /// assert_eq!(o, Less);
885 ///
886 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::from_signeds(-3i8, 5), 10);
887 /// assert_eq!(e.to_string(), "-0.45117");
888 /// assert_eq!(o, Greater);
889 ///
890 /// let (e, o) = Float::exp_x_minus_1_rational_prec(Rational::ZERO, 10);
891 /// assert_eq!(e.to_string(), "0.0");
892 /// assert_eq!(o, Equal);
893 /// ```
894 #[inline]
895 pub fn exp_x_minus_1_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
896 Self::exp_x_minus_1_rational_prec_round_ref(&x, prec, Nearest)
897 }
898
899 /// Computes $e^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
900 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
901 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded value is less
902 /// than, equal to, or greater than the exact value.
903 ///
904 /// If the value is equidistant from two [`Float`]s with the specified precision, the [`Float`]
905 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
906 /// the `Nearest` rounding mode.
907 ///
908 /// $$
909 /// f(x,p) = e^x-1+\varepsilon,
910 /// $$
911 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$ (unless the result overflows
912 /// or underflows; see below).
913 ///
914 /// The output has precision `prec`.
915 ///
916 /// Special cases:
917 /// - $f(0,p)=0$.
918 ///
919 /// Overflow and underflow:
920 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
921 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
922 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
923 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
924 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
925 ///
926 /// Unlike $e^x$, $e^x-1$ never underflows to zero for large negative $x$: it instead tends to
927 /// $-1$.
928 ///
929 /// If you want to use a rounding mode other than `Nearest`, consider using
930 /// [`Float::exp_x_minus_1_rational_prec_round_ref`] instead.
931 ///
932 /// # Worst-case complexity
933 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
934 ///
935 /// $M(n, m) = O(n \log n + m \log m)$
936 ///
937 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
938 /// `x.significant_bits()`.
939 ///
940 /// # Panics
941 /// Panics if `prec` is zero.
942 ///
943 /// # Examples
944 /// ```
945 /// use malachite_base::num::basic::traits::Zero;
946 /// use malachite_float::Float;
947 /// use malachite_q::Rational;
948 /// use std::cmp::Ordering::*;
949 ///
950 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
951 /// assert_eq!(e.to_string(), "0.812");
952 /// assert_eq!(o, Less);
953 ///
954 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
955 /// assert_eq!(e.to_string(), "0.82211876");
956 /// assert_eq!(o, Less);
957 ///
958 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::from_signeds(-3i8, 5), 10);
959 /// assert_eq!(e.to_string(), "-0.45117");
960 /// assert_eq!(o, Greater);
961 ///
962 /// let (e, o) = Float::exp_x_minus_1_rational_prec_ref(&Rational::ZERO, 10);
963 /// assert_eq!(e.to_string(), "0.0");
964 /// assert_eq!(o, Equal);
965 /// ```
966 #[inline]
967 pub fn exp_x_minus_1_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
968 Self::exp_x_minus_1_rational_prec_round_ref(x, prec, Nearest)
969 }
970
971 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result with the specified rounding
972 /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
973 /// the rounded value is less than, equal to, or greater than the exact value. Although `NaN`s
974 /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
975 /// `Equal`.
976 ///
977 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
978 /// description of the possible rounding modes.
979 ///
980 /// $$
981 /// f(x,m) = e^x-1+\varepsilon.
982 /// $$
983 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
984 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
985 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
986 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
987 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
988 ///
989 /// If the output has a precision, it is the precision of the input.
990 ///
991 /// Special cases:
992 /// - $f(\text{NaN},m)=\text{NaN}$
993 /// - $f(\infty,m)=\infty$
994 /// - $f(-\infty,m)=-1$
995 /// - $f(\pm0.0,m)=\pm0.0$
996 ///
997 /// Overflow and underflow:
998 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
999 /// returned instead.
1000 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1001 /// returned instead.
1002 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1003 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned instead.
1004 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
1005 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1006 /// instead.
1007 ///
1008 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1009 ///
1010 /// If you want to specify an output precision, consider using
1011 /// [`Float::exp_x_minus_1_prec_round`] instead. If you know you'll be using the `Nearest`
1012 /// rounding mode, consider using [`Float::exp_x_minus_1`] instead.
1013 ///
1014 /// # Worst-case complexity
1015 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1016 ///
1017 /// $M(n) = O(n \log n)$
1018 ///
1019 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1020 ///
1021 /// # Panics
1022 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1023 /// precision. (The result cannot be represented exactly whenever the input is finite and
1024 /// nonzero.)
1025 ///
1026 /// # Examples
1027 /// ```
1028 /// use malachite_base::rounding_modes::RoundingMode::*;
1029 /// use malachite_float::Float;
1030 /// use std::cmp::Ordering::*;
1031 ///
1032 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1033 /// .0
1034 /// .exp_x_minus_1_round(Floor);
1035 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713512");
1036 /// assert_eq!(o, Less);
1037 ///
1038 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1039 /// .0
1040 /// .exp_x_minus_1_round(Ceiling);
1041 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713528");
1042 /// assert_eq!(o, Greater);
1043 /// ```
1044 #[inline]
1045 pub fn exp_x_minus_1_round(self, rm: RoundingMode) -> (Self, Ordering) {
1046 let prec = self.significant_bits();
1047 self.exp_x_minus_1_prec_round(prec, rm)
1048 }
1049
1050 /// Computes $e^x-1$, where $x$ is a [`Float`], rounding the result with the specified rounding
1051 /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
1052 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
1053 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1054 /// returns `Equal`.
1055 ///
1056 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1057 /// description of the possible rounding modes.
1058 ///
1059 /// $$
1060 /// f(x,m) = e^x-1+\varepsilon.
1061 /// $$
1062 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1063 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1064 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
1065 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1066 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1067 ///
1068 /// If the output has a precision, it is the precision of the input.
1069 ///
1070 /// Special cases:
1071 /// - $f(\text{NaN},m)=\text{NaN}$
1072 /// - $f(\infty,m)=\infty$
1073 /// - $f(-\infty,m)=-1$
1074 /// - $f(\pm0.0,m)=\pm0.0$
1075 ///
1076 /// Overflow and underflow:
1077 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1078 /// returned instead.
1079 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1080 /// returned instead.
1081 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1082 /// - If $-2^{-2^{30}}<f(x,m)<0$ and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned instead.
1083 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$ and $m$ is `Nearest`, $-0.0$ is returned instead.
1084 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$ and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1085 /// instead.
1086 ///
1087 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1088 ///
1089 /// If you want to specify an output precision, consider using
1090 /// [`Float::exp_x_minus_1_prec_round_ref`] instead. If you know you'll be using the `Nearest`
1091 /// rounding mode, consider using `(&Float).exp_x_minus_1()` instead.
1092 ///
1093 /// # Worst-case complexity
1094 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1095 ///
1096 /// $M(n) = O(n \log n)$
1097 ///
1098 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1099 ///
1100 /// # Panics
1101 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1102 /// precision. (The result cannot be represented exactly whenever the input is finite and
1103 /// nonzero.)
1104 ///
1105 /// # Examples
1106 /// ```
1107 /// use malachite_base::rounding_modes::RoundingMode::*;
1108 /// use malachite_float::Float;
1109 /// use std::cmp::Ordering::*;
1110 ///
1111 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1112 /// .0
1113 /// .exp_x_minus_1_round_ref(Floor);
1114 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713512");
1115 /// assert_eq!(o, Less);
1116 ///
1117 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1118 /// .0
1119 /// .exp_x_minus_1_round_ref(Ceiling);
1120 /// assert_eq!(e.to_string(), "1.7182818284590452353602874713528");
1121 /// assert_eq!(o, Greater);
1122 /// ```
1123 #[inline]
1124 pub fn exp_x_minus_1_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1125 self.exp_x_minus_1_prec_round_ref(self.significant_bits(), rm)
1126 }
1127
1128 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result to the specified
1129 /// precision and with the specified rounding mode. An [`Ordering`] is returned, indicating
1130 /// whether the rounded value is less than, equal to, or greater than the exact value. Although
1131 /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
1132 /// `NaN` it also returns `Equal`.
1133 ///
1134 /// See [`RoundingMode`] for a description of the possible rounding modes.
1135 ///
1136 /// $$
1137 /// x \gets e^x-1+\varepsilon.
1138 /// $$
1139 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1140 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1141 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$.
1142 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1143 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$.
1144 ///
1145 /// If the output has a precision, it is `prec`.
1146 ///
1147 /// See the [`Float::exp_x_minus_1_prec_round`] documentation for information on special cases.
1148 ///
1149 /// If you know you'll be using `Nearest`, consider using [`Float::exp_x_minus_1_prec_assign`]
1150 /// instead. If you know that your target precision is the precision of the input, consider
1151 /// using [`Float::exp_x_minus_1_round_assign`] instead. If both of these things are true,
1152 /// consider using [`Float::exp_x_minus_1_assign`] instead.
1153 ///
1154 /// # Worst-case complexity
1155 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1156 ///
1157 /// $M(n, m) = O(n \log n + m)$
1158 ///
1159 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1160 /// `self.significant_bits()`.
1161 ///
1162 /// # Panics
1163 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1164 /// with the given precision. (The result cannot be represented exactly whenever the input is
1165 /// finite and nonzero.)
1166 ///
1167 /// # Examples
1168 /// ```
1169 /// use malachite_base::rounding_modes::RoundingMode::*;
1170 /// use malachite_float::Float;
1171 /// use std::cmp::Ordering::*;
1172 ///
1173 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1174 /// assert_eq!(x.exp_x_minus_1_prec_round_assign(20, Floor), Less);
1175 /// assert_eq!(x.to_string(), "1.7182808");
1176 ///
1177 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1178 /// assert_eq!(x.exp_x_minus_1_prec_round_assign(20, Ceiling), Greater);
1179 /// assert_eq!(x.to_string(), "1.7182827");
1180 /// ```
1181 #[inline]
1182 pub fn exp_x_minus_1_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1183 let (result, o) = core::mem::take(self).exp_x_minus_1_prec_round(prec, rm);
1184 *self = result;
1185 o
1186 }
1187
1188 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result to the nearest
1189 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
1190 /// rounded value is less than, equal to, or greater than the exact value. Although `NaN`s are
1191 /// not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
1192 /// returns `Equal`.
1193 ///
1194 /// If the result is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1195 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1196 /// the `Nearest` rounding mode.
1197 ///
1198 /// $$
1199 /// x \gets e^x-1+\varepsilon.
1200 /// $$
1201 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1202 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1203 /// |e^x-1|\rfloor-p}$.
1204 ///
1205 /// If the output has a precision, it is `prec`.
1206 ///
1207 /// See the [`Float::exp_x_minus_1_prec`] documentation for information on special cases.
1208 ///
1209 /// If you want to use a rounding mode other than `Nearest`, consider using
1210 /// [`Float::exp_x_minus_1_prec_round_assign`] instead. If you know that your target precision
1211 /// is the precision of the input, consider using [`Float::exp_x_minus_1_assign`] instead.
1212 ///
1213 /// # Worst-case complexity
1214 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1215 ///
1216 /// $M(n, m) = O(n \log n + m)$
1217 ///
1218 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1219 /// `self.significant_bits()`.
1220 ///
1221 /// # Panics
1222 /// Panics if `prec` is zero.
1223 ///
1224 /// # Examples
1225 /// ```
1226 /// use malachite_float::Float;
1227 /// use std::cmp::Ordering::*;
1228 ///
1229 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1230 /// assert_eq!(x.exp_x_minus_1_prec_assign(20), Greater);
1231 /// assert_eq!(x.to_string(), "1.7182827");
1232 /// ```
1233 #[inline]
1234 pub fn exp_x_minus_1_prec_assign(&mut self, prec: u64) -> Ordering {
1235 self.exp_x_minus_1_prec_round_assign(prec, Nearest)
1236 }
1237
1238 /// Computes $e^x-1$, where $x$ is a [`Float`], in place, rounding the result with the specified
1239 /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded value is less
1240 /// than, equal to, or greater than the exact value. Although `NaN`s are not comparable to any
1241 /// [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
1242 ///
1243 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1244 /// description of the possible rounding modes.
1245 ///
1246 /// $$
1247 /// x \gets e^x-1+\varepsilon.
1248 /// $$
1249 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1250 /// - If $e^x-1$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1251 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p+1}$, where $p$ is the precision of the input.
1252 /// - If $e^x-1$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1253 /// 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1254 ///
1255 /// If the output has a precision, it is the precision of the input.
1256 ///
1257 /// See the [`Float::exp_x_minus_1_round`] documentation for information on special cases.
1258 ///
1259 /// If you want to specify an output precision, consider using
1260 /// [`Float::exp_x_minus_1_prec_round_assign`] instead. If you know you'll be using the
1261 /// `Nearest` rounding mode, consider using [`Float::exp_x_minus_1_assign`] instead.
1262 ///
1263 /// # Worst-case complexity
1264 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1265 ///
1266 /// $M(n) = O(n \log n)$
1267 ///
1268 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1269 ///
1270 /// # Panics
1271 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1272 /// precision. (The result cannot be represented exactly whenever the input is finite and
1273 /// nonzero.)
1274 ///
1275 /// # Examples
1276 /// ```
1277 /// use malachite_base::rounding_modes::RoundingMode::*;
1278 /// use malachite_float::Float;
1279 /// use std::cmp::Ordering::*;
1280 ///
1281 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1282 /// assert_eq!(x.exp_x_minus_1_round_assign(Floor), Less);
1283 /// assert_eq!(x.to_string(), "1.7182818284590452353602874713512");
1284 ///
1285 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1286 /// assert_eq!(x.exp_x_minus_1_round_assign(Ceiling), Greater);
1287 /// assert_eq!(x.to_string(), "1.7182818284590452353602874713528");
1288 /// ```
1289 #[inline]
1290 pub fn exp_x_minus_1_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1291 let prec = self.significant_bits();
1292 self.exp_x_minus_1_prec_round_assign(prec, rm)
1293 }
1294}
1295
1296impl ExpXMinus1 for Float {
1297 type Output = Self;
1298
1299 /// Computes $e^x-1$, where $x$ is a [`Float`], taking the [`Float`] by value.
1300 ///
1301 /// If the output has a precision, it is the precision of the input. If the result is
1302 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1303 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1304 /// rounding mode.
1305 ///
1306 /// $$
1307 /// f(x) = e^x-1+\varepsilon.
1308 /// $$
1309 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1310 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1311 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1312 ///
1313 /// Special cases:
1314 /// - $f(\text{NaN})=\text{NaN}$
1315 /// - $f(\infty)=\infty$
1316 /// - $f(-\infty)=-1$
1317 /// - $f(\pm0.0)=\pm0.0$
1318 ///
1319 /// Overflow and underflow:
1320 /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1321 /// - If $-2^{-2^{30}-1}\leq f(x)<0$, $-0.0$ is returned instead.
1322 /// - If $-2^{-2^{30}}<f(x)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1323 ///
1324 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1325 ///
1326 /// If you want to use a rounding mode other than `Nearest`, consider using
1327 /// [`Float::exp_x_minus_1_round`] instead. If you want to specify the output precision,
1328 /// consider using [`Float::exp_x_minus_1_prec`]. If you want both of these things, consider
1329 /// using [`Float::exp_x_minus_1_prec_round`].
1330 ///
1331 /// # Worst-case complexity
1332 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1333 ///
1334 /// $M(n) = O(n \log n)$
1335 ///
1336 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1337 ///
1338 /// # Examples
1339 /// ```
1340 /// use malachite_base::num::arithmetic::traits::ExpXMinus1;
1341 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1342 /// use malachite_float::Float;
1343 ///
1344 /// assert!(Float::NAN.exp_x_minus_1().is_nan());
1345 /// assert_eq!(Float::INFINITY.exp_x_minus_1(), Float::INFINITY);
1346 /// assert_eq!(Float::NEGATIVE_INFINITY.exp_x_minus_1().to_string(), "-1.0");
1347 /// assert_eq!(Float::ONE.exp_x_minus_1().to_string(), "2.0");
1348 /// ```
1349 #[inline]
1350 fn exp_x_minus_1(self) -> Self {
1351 let prec = self.significant_bits();
1352 self.exp_x_minus_1_prec(prec).0
1353 }
1354}
1355
1356impl ExpXMinus1 for &Float {
1357 type Output = Float;
1358
1359 /// Computes $e^x-1$, where $x$ is a [`Float`], taking the [`Float`] by reference.
1360 ///
1361 /// If the output has a precision, it is the precision of the input. If the result is
1362 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1363 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1364 /// rounding mode.
1365 ///
1366 /// $$
1367 /// f(x) = e^x-1+\varepsilon.
1368 /// $$
1369 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1370 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1371 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1372 ///
1373 /// Special cases:
1374 /// - $f(\text{NaN})=\text{NaN}$
1375 /// - $f(\infty)=\infty$
1376 /// - $f(-\infty)=-1$
1377 /// - $f(\pm0.0)=\pm0.0$
1378 ///
1379 /// Overflow and underflow:
1380 /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1381 /// - If $-2^{-2^{30}-1}\leq f(x)<0$, $-0.0$ is returned instead.
1382 /// - If $-2^{-2^{30}}<f(x)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1383 ///
1384 /// (A positive result never underflows: $e^x-1>x$ for positive $x$.)
1385 ///
1386 /// If you want to use a rounding mode other than `Nearest`, consider using
1387 /// [`Float::exp_x_minus_1_round_ref`] instead. If you want to specify the output precision,
1388 /// consider using [`Float::exp_x_minus_1_prec_ref`]. If you want both of these things, consider
1389 /// using [`Float::exp_x_minus_1_prec_round_ref`].
1390 ///
1391 /// # Worst-case complexity
1392 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1393 ///
1394 /// $M(n) = O(n \log n)$
1395 ///
1396 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1397 ///
1398 /// # Examples
1399 /// ```
1400 /// use malachite_base::num::arithmetic::traits::ExpXMinus1;
1401 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1402 /// use malachite_float::Float;
1403 ///
1404 /// assert!((&Float::NAN).exp_x_minus_1().is_nan());
1405 /// assert_eq!((&Float::INFINITY).exp_x_minus_1(), Float::INFINITY);
1406 /// assert_eq!(
1407 /// (&Float::NEGATIVE_INFINITY).exp_x_minus_1().to_string(),
1408 /// "-1.0"
1409 /// );
1410 /// assert_eq!((&Float::ONE).exp_x_minus_1().to_string(), "2.0");
1411 /// ```
1412 #[inline]
1413 fn exp_x_minus_1(self) -> Float {
1414 self.exp_x_minus_1_prec_round_ref(self.significant_bits(), Nearest)
1415 .0
1416 }
1417}
1418
1419impl ExpXMinus1Assign for Float {
1420 /// Computes $e^x-1$, where $x$ is a [`Float`], in place.
1421 ///
1422 /// If the output has a precision, it is the precision of the input. If the result is
1423 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1424 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1425 /// rounding mode.
1426 ///
1427 /// $$
1428 /// x \gets e^x-1+\varepsilon.
1429 /// $$
1430 /// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1431 /// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1432 /// |e^x-1|\rfloor-p}$, where $p$ is the precision of the input.
1433 ///
1434 /// See the [`Float::exp_x_minus_1`] documentation for information on special cases.
1435 ///
1436 /// If you want to use a rounding mode other than `Nearest`, consider using
1437 /// [`Float::exp_x_minus_1_round_assign`] instead. If you want to specify the output precision,
1438 /// consider using [`Float::exp_x_minus_1_prec_assign`]. If you want both of these things,
1439 /// consider using [`Float::exp_x_minus_1_prec_round_assign`].
1440 ///
1441 /// # Worst-case complexity
1442 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1443 ///
1444 /// $M(n) = O(n \log n)$
1445 ///
1446 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1447 ///
1448 /// # Examples
1449 /// ```
1450 /// use malachite_base::num::arithmetic::traits::ExpXMinus1Assign;
1451 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One};
1452 /// use malachite_float::Float;
1453 ///
1454 /// let mut x = Float::NAN;
1455 /// x.exp_x_minus_1_assign();
1456 /// assert!(x.is_nan());
1457 ///
1458 /// let mut x = Float::INFINITY;
1459 /// x.exp_x_minus_1_assign();
1460 /// assert_eq!(x, Float::INFINITY);
1461 ///
1462 /// let mut x = Float::NEGATIVE_INFINITY;
1463 /// x.exp_x_minus_1_assign();
1464 /// assert_eq!(x.to_string(), "-1.0");
1465 ///
1466 /// let mut x = Float::ONE;
1467 /// x.exp_x_minus_1_assign();
1468 /// assert_eq!(x.to_string(), "2.0");
1469 /// ```
1470 #[inline]
1471 fn exp_x_minus_1_assign(&mut self) {
1472 let prec = self.significant_bits();
1473 self.exp_x_minus_1_prec_round_assign(prec, Nearest);
1474 }
1475}
1476
1477/// Computes $e^x-1$ for a primitive float. Using this function is more accurate than using the
1478/// primitive float `exp_m1` function (the standard library's `exp_m1` is not correctly rounded).
1479///
1480/// $$
1481/// f(x) = e^x-1+\varepsilon.
1482/// $$
1483/// - If $e^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1484/// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$,
1485/// where $p$ is precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1486/// [`f64`], but less if the output is subnormal).
1487///
1488/// Special cases:
1489/// - $f(\text{NaN})=\text{NaN}$
1490/// - $f(\infty)=\infty$
1491/// - $f(-\infty)=-1$
1492/// - $f(\pm0.0)=\pm0.0$
1493///
1494/// If the result overflows, $\infty$ is returned, and if it underflows, $-0.0$ is returned. (A
1495/// positive result never underflows: $e^x-1>x$ for positive $x$.)
1496///
1497/// # Worst-case complexity
1498/// Constant time and additional memory.
1499///
1500/// # Examples
1501/// ```
1502/// use malachite_base::num::basic::traits::NegativeInfinity;
1503/// use malachite_base::num::float::NiceFloat;
1504/// use malachite_float::float::arithmetic::exp_x_minus_1::primitive_float_exp_x_minus_1;
1505///
1506/// assert!(primitive_float_exp_x_minus_1(f32::NAN).is_nan());
1507/// assert_eq!(
1508/// NiceFloat(primitive_float_exp_x_minus_1(f32::INFINITY)),
1509/// NiceFloat(f32::INFINITY)
1510/// );
1511/// assert_eq!(
1512/// NiceFloat(primitive_float_exp_x_minus_1(f32::NEGATIVE_INFINITY)),
1513/// NiceFloat(-1.0)
1514/// );
1515/// assert_eq!(
1516/// NiceFloat(primitive_float_exp_x_minus_1(1.0f32)),
1517/// NiceFloat(1.7182819)
1518/// );
1519/// ```
1520#[inline]
1521#[allow(clippy::type_repetition_in_bounds)]
1522pub fn primitive_float_exp_x_minus_1<T: PrimitiveFloat>(x: T) -> T
1523where
1524 Float: From<T> + PartialOrd<T>,
1525 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1526{
1527 emulate_float_to_float_fn(Float::exp_x_minus_1_prec, x)
1528}
1529
1530/// Computes $e^x-1$, where $x$ is a [`Rational`], returning the result as a primitive float.
1531///
1532/// $$
1533/// f(x) = e^x-1+\varepsilon.
1534/// $$
1535/// - If $e^x-1$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
1536/// - If $e^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |e^x-1|\rfloor-p}$,
1537/// where $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1538/// [`f64`], but less if the output is subnormal).
1539///
1540/// Special cases:
1541/// - $f(0)=0$
1542///
1543/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a small nonzero
1544/// `x` may give $\pm0.0$. Unlike $e^x$, a large negative `x` does not underflow to zero; it gives
1545/// `-1.0`.
1546///
1547/// # Worst-case complexity
1548/// $T(m) = O(m (\log m)^2 \log\log m)$
1549///
1550/// $M(m) = O(m \log m)$
1551///
1552/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
1553///
1554/// # Examples
1555/// ```
1556/// use malachite_base::num::basic::traits::Zero;
1557/// use malachite_base::num::float::NiceFloat;
1558/// use malachite_float::float::arithmetic::exp_x_minus_1::primitive_float_exp_x_minus_1_rational;
1559/// use malachite_q::Rational;
1560///
1561/// assert_eq!(
1562/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1563/// &Rational::ZERO
1564/// )),
1565/// NiceFloat(0.0)
1566/// );
1567/// assert_eq!(
1568/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1569/// &Rational::from_unsigneds(1u8, 3)
1570/// )),
1571/// NiceFloat(0.3956124250860895)
1572/// );
1573/// assert_eq!(
1574/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1575/// &Rational::from(10000)
1576/// )),
1577/// NiceFloat(f64::INFINITY)
1578/// );
1579/// assert_eq!(
1580/// NiceFloat(primitive_float_exp_x_minus_1_rational::<f64>(
1581/// &Rational::from(-10000)
1582/// )),
1583/// NiceFloat(-1.0)
1584/// );
1585/// ```
1586#[inline]
1587#[allow(clippy::type_repetition_in_bounds)]
1588pub fn primitive_float_exp_x_minus_1_rational<T: PrimitiveFloat>(x: &Rational) -> T
1589where
1590 Float: PartialOrd<T>,
1591 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1592{
1593 emulate_rational_to_float_fn(Float::exp_x_minus_1_rational_prec_ref, x)
1594}