malachite_float/float/arithmetic/exp.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright © 1999-2025 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
15// Port of MPFR's exponential. `mpfr_exp` (`exp.c`) is a dispatcher; the medium-precision workhorse
16// `mpfr_exp_2` (`exp_2.c`) uses Brent's method -- reduce x = n*log(2) + 2^K*r, sum the Taylor
17// series for the small r, raise to the 2^K power by K squarings, then scale by 2^n -- with the
18// series summed in fixed point. That fixed point is represented here as a malachite `Integer`
19// mantissa paired with an `i64` 2-exponent (MPFR's `mpz_t` + `mpfr_exp_t`).
20//
21// The Paterson-Stockmeyer series (exp2_aux2) and the high-precision exp_3 are not yet ported.
22
23use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
24use crate::{
25 Float, WIDTH_MINUS_1, emulate_float_to_float_fn, emulate_rational_to_float_fn,
26 floor_and_ceiling,
27};
28use alloc::vec;
29use core::cmp::Ordering::{self, Equal, Greater, Less};
30use core::cmp::max;
31use core::mem::swap;
32use malachite_base::fail_on_untested_path;
33use malachite_base::num::arithmetic::traits::{
34 CeilingLogBase2, Exp, ExpAssign, FloorRoot, FloorSqrt, IsPowerOf2, NegAssign, Parity, PowerOf2,
35 ShrRoundAssign, Sign, Square, SquareAssign, WrappingAddAssign,
36};
37use malachite_base::num::basic::floats::PrimitiveFloat;
38use malachite_base::num::basic::integers::PrimitiveInt;
39use malachite_base::num::basic::traits::{
40 Infinity as InfinityTrait, NaN as NaNTrait, One, Zero as ZeroTrait,
41};
42use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom, WrappingFrom};
43use malachite_base::num::logic::traits::SignificantBits;
44use malachite_base::rounding_modes::RoundingMode::{
45 self, Ceiling, Down, Exact, Floor, Nearest, Up,
46};
47use malachite_nz::integer::Integer;
48use malachite_nz::natural::Natural;
49use malachite_nz::natural::arithmetic::float::round::float_can_round;
50use malachite_nz::platform::{Limb, SignedLimb};
51use malachite_q::Rational;
52
53// If the number of bits `k` of `z` exceeds `q`, divides `z` by `2 ^ (k - q)` (flooring) and returns
54// `k - q`; otherwise leaves `z` unchanged and returns 0.
55//
56// This is `mpz_normalize` from `exp_2.c`, MPFR 4.2.2.
57fn mpz_normalize(z: Integer, q: i64) -> (Integer, i64) {
58 let k = z.significant_bits();
59 if q < 0 || k > u64::exact_from(q) {
60 let shift = i64::exact_from(k) - q;
61 (z >> shift, shift)
62 } else {
63 // Currently unreachable from the naive series (`exp2_aux` always grows `t`/`rr` past `q`
64 // bits before truncating, and the squaring loop doubles past `q`); exercised once the
65 // Paterson-Stockmeyer path (`exp2_aux2`) is ported.
66 (z, 0)
67 }
68}
69
70// Shifts `z` so that its 2-exponent becomes `target`: right (flooring) by `target - expz` if
71// `target > expz`, otherwise left by `expz - target`. Returns `target`.
72//
73// This is `mpz_normalize2` from `exp_2.c`, MPFR 4.2.2. (A negative shift count reverses direction,
74// so the single `>>` covers both of MPFR's branches.)
75fn mpz_normalize2(z: Integer, expz: i64, target: i64) -> (Integer, i64) {
76 (z >> (target - expz), target)
77}
78
79// Returns the integer mantissa `m` and 2-exponent `e` of a finite nonzero `x`, so that `x = m *
80// 2^e` (the sign is carried by `m`). For a Malachite `Float`, `m` is the significand as a signed
81// integer and `e = exponent - significand_bits` (verified against 1.0: significand 2^63, exponent
82// 1, giving 2^63 * 2^(1-64) = 1).
83//
84// This is equivalent to `mpfr_get_z_2exp` from MPFR 4.2.2.
85fn get_z_2exp(x: Float) -> (Integer, i64) {
86 if let Finite {
87 sign,
88 exponent,
89 significand,
90 ..
91 } = x.0
92 {
93 let bits = significand.significant_bits();
94 let m = Integer::from_sign_and_abs(sign, significand);
95 (m, i64::from(exponent) - i64::exact_from(bits))
96 } else {
97 unreachable!()
98 }
99}
100
101// Computes `s = 1 + r/1! + r^2/2! + ... + r^l/l!` (continuing while the term is still significant
102// at precision `q`) in fixed point, where the returned `Integer` `s` and 2-exponent `exps` satisfy
103// (sum) = s * 2^exps. `r` must be pure FP (here it is positive and tiny). The naive method, O(l)
104// multiplications; the absolute error on the sum is less than `3*l*(l+1)*2^(-q)`, and that
105// `3*l*(l+1)` bound is the returned value. (`l` stays small for the precisions `exp_2` handles, so
106// the bound fits in a `u64`.)
107//
108// This is `mpfr_exp2_aux` from `exp_2.c`, MPFR 4.2.2.
109fn exp2_aux(r: Float, q: u64) -> (Integer, i64, u64) {
110 let qi = i64::exact_from(q);
111 let mut expt: i64 = 0;
112 let exps: i64 = 1 - qi; // s = 2^(q-1), i.e. the value 1
113 let mut t = Integer::ONE;
114 let mut s = Integer::power_of_2(q - 1);
115 let (mut rr, mut expr) = get_z_2exp(r); // rr * 2^expr = r, no error
116 let mut l: u64 = 0;
117 loop {
118 l += 1;
119 t *= &rr;
120 expt += expr;
121 let sbit = i64::exact_from(s.significant_bits());
122 let tbit = i64::exact_from(t.significant_bits());
123 let dif = exps + sbit - expt - tbit;
124 // truncate the bits of t that are below ulp(s) = 2^(1-q); error at most 2^(1-q)
125 let (t2, sh) = mpz_normalize(t, qi - dif);
126 t = t2;
127 expt += sh;
128 if l > 1 {
129 // divide by l to build r^l/l! (t >= 0, so truncation equals MPFR's floored division)
130 if l.is_power_of_2() {
131 // GMP doesn't optimize the power-of-2 case
132 t >>= l.ceiling_log_base_2();
133 } else {
134 t /= Integer::from(l);
135 }
136 debug_assert_eq!(expt, exps);
137 }
138 if t == 0 {
139 break;
140 }
141 s += &t; // exact
142 // keep rr the same size as t: the error on rr stays at most ulp(t) = ulp(s)
143 let tbit = i64::exact_from(t.significant_bits());
144 let (rr2, sh) = mpz_normalize(rr, tbit);
145 rr = rr2;
146 expr += sh;
147 }
148 (s, exps, 3 * l * (l + 1))
149}
150
151// Precision (in bits) at which `exp_2` switches from the naive `exp2_aux` (square-root `K`) to the
152// Paterson-Stockmeyer `exp2_aux2` (cube-root `K`). MPFR tunes `MPFR_EXP_2_THRESHOLD` per platform;
153// this is the generic default (`generic/mparam.h`), pending Malachite tuning.
154const EXP_2_THRESHOLD: u64 = 100;
155
156// Computes `s = 1 + r/1! + r^2/2! + ... + r^l/l!` (continuing while r^l/l! is still significant at
157// precision `q`) in fixed point, where the returned `Integer` `s` and 2-exponent `exps` satisfy
158// (sum) = s * 2^exps. `r` must be pure FP with exponent < 0 (here it is positive and tiny). Uses
159// the Paterson-Stockmeyer scheme: about `m + l/m` full multiplications (`2*sqrt(l)` for `m =
160// sqrt(l)`), versus `exp2_aux`'s O(l). The error is bounded by `l^2 + 4*l` ulps, and that `l*(l+4)`
161// bound is the returned value.
162//
163// This is `mpfr_exp2_aux2` from `exp_2.c`, MPFR 4.2.2.
164fn exp2_aux2(r: Float, q: u64) -> (Integer, i64, u64) {
165 let qi = i64::exact_from(q);
166 let one_minus_q = 1 - qi;
167 // estimate the value of l, then m ~ sqrt(l); we access R[2], so we need m >= 2
168 let expr0 = i64::from(r.get_exponent().unwrap());
169 debug_assert!(expr0 < 0);
170 let l_est = q / u64::exact_from(-expr0);
171 let m = max(2, usize::exact_from(l_est.floor_sqrt()));
172 // r_pows[i] = r^i (integer mantissa), exp_r_pows[i] its 2-exponent
173 let mut r_pows = vec![Integer::ZERO; m + 1];
174 let mut exp_r_pows = vec![0i64; m + 1];
175 let exps = one_minus_q; // 1 ulp = 2^(1-q)
176 let mut s = Integer::ZERO;
177 let (r1, e1) = get_z_2exp(r); // exact: no error
178 // normalize R[1] to exponent 1 - q (error <= 1 ulp)
179 let r1 = mpz_normalize2(r1, e1, one_minus_q).0;
180 r_pows[1] = r1;
181 exp_r_pows[1] = one_minus_q;
182 // R[2] = R[1]^2 >> (q - 1) (err <= 3 ulps)
183 let qm1 = q - 1;
184 r_pows[2] = (&r_pows[1]).square() >> qm1;
185 exp_r_pows[2] = one_minus_q;
186 for i in 3..=m {
187 // err(R[i]) <= 2*i-1 ulps
188 let t = if i.odd() {
189 &r_pows[i - 1] * &r_pows[1]
190 } else {
191 (&r_pows[i >> 1]).square()
192 };
193 r_pows[i] = t >> qm1;
194 exp_r_pows[i] = one_minus_q;
195 }
196 r_pows[0] = Integer::power_of_2(q - 1); // R[0] = 1
197 exp_r_pows[0] = one_minus_q;
198 let mut rr = Integer::ONE;
199 let mut expr: i64 = 0; // rr contains r^l/l!; by induction err(rr) <= 2*l ulps
200 let mut l: u64 = 0;
201 let mut ql = q; // precision used for the current giant step
202 loop {
203 let one_minus_ql = 1 - i64::exact_from(ql);
204 // all R[i] (i < m) must have exponent 1 - ql
205 if l != 0 {
206 for (r_pow, exp_r_pow) in r_pows[..m].iter_mut().zip(exp_r_pows[..m].iter_mut()) {
207 let z = core::mem::replace(r_pow, Integer::ZERO);
208 (*r_pow, *exp_r_pow) = mpz_normalize2(z, *exp_r_pow, one_minus_ql);
209 }
210 }
211 // t = R[m-1] normalized to exponent 1 - ql (err(t) <= 2*m-1 ulps)
212 let (mut t, mut expt) =
213 mpz_normalize2(r_pows[m - 1].clone(), exp_r_pows[m - 1], one_minus_ql);
214 // t = 1 + r/(l+1) + ... + r^(m-1)*l!/(l+m-1)! via Horner's scheme
215 for i in (0..m - 1).rev() {
216 t /= Integer::from(l + i as u64 + 1); // err(t) += 1 ulp
217 t += &r_pows[i];
218 }
219 // multiply t by r^l/l! and add to s
220 t *= &rr;
221 expt += expr;
222 let (t, et) = mpz_normalize2(t, expt, exps);
223 debug_assert_eq!(et, exps);
224 s += &t; // no error here
225 // update rr to r^(l+m)/(l+m)!
226 let mut t = &rr * &r_pows[m]; // err(t) <= err(rr) + 2m-1
227 expr += exp_r_pows[m];
228 let mut tmp = Integer::ONE;
229 for i in 1..=m {
230 tmp *= Integer::from(l + i as u64);
231 }
232 t /= tmp; // err(t) <= err(rr) + 2m
233 l += m as u64;
234 if t == 0 {
235 break;
236 }
237 let (rr2, sh) = mpz_normalize(t, i64::exact_from(ql));
238 rr = rr2;
239 expr += sh;
240 // in late giant steps `ql` can go <= 0 (s has grown past the working precision), so
241 // normalizing t to ql bits can shift it away entirely; rr is then 0.
242 let rrbit = if rr == 0 {
243 1
244 } else {
245 i64::exact_from(rr.significant_bits())
246 };
247 let sbit = i64::exact_from(s.significant_bits());
248 ql = (qi - exps - sbit + expr + rrbit) as u64;
249 // MPFR's own `(size_t)` cast here is admittedly dubious (see its TODO), but the operands
250 // cluster near -q, far from the wrap, so the unsigned and signed comparisons agree.
251 if (expr as u64).wrapping_add(rrbit as u64) <= q.wrapping_neg() {
252 break;
253 }
254 }
255 (s, exps, l * (l + 4))
256}
257
258// Precision (in bits) at or above which `exp` uses the binary-splitting `exp_3` (O(M(n) log(n)^2))
259// instead of `exp_2`. MPFR's generic `MPFR_EXP_THRESHOLD` default (`generic/mparam.h`), untuned.
260const EXP_THRESHOLD: u64 = 25000;
261
262// Extracts the `i`-th binary-splitting chunk of the mantissa of `p`, where `0 <= |p| < 1`, carrying
263// `p`'s sign. With `B = 2 ^ Limb::WIDTH`: chunk 0 is `floor(|p| * B)` (the top limb), and for `i >
264// 0`, chunk `i` is `(|p| * B^(2^i)) mod B^(2^(i-1))` -- the window of `2^(i-1)` limbs ending
265// `2^(i-1)` limbs below where chunk `i - 1` ends.
266//
267// This is `mpfr_extract` from `extract.c`, MPFR 4.2.2.
268fn extract(p: &Float, i: u64) -> Integer {
269 if let Finite {
270 sign, significand, ..
271 } = &p.0
272 {
273 let limbs = significand.as_limbs_asc();
274 let size_p = limbs.len();
275 let two_i = usize::power_of_2(i);
276 let two_i_2 = if i == 0 { 1 } else { two_i >> 1 };
277 let mut y = vec![0 as Limb; two_i_2];
278 if size_p < two_i {
279 // The window extends past the bottom of the mantissa: zero-fill and copy what's there.
280 if size_p >= two_i_2 {
281 let count = size_p - two_i_2;
282 y[two_i - size_p..][..count].copy_from_slice(&limbs[..count]);
283 } else {
284 // The whole window is below the mantissa (chunk all zero). Unreachable from
285 // `exp_3`: it only extracts chunks `i <= prec_x`, and `size_p > 2^(prec_x - 1) >=
286 // two_i_2`.
287 fail_on_untested_path("extract, window entirely below the mantissa");
288 }
289 } else {
290 y.copy_from_slice(&limbs[size_p - two_i..][..two_i_2]);
291 }
292 Integer::from_sign_and_abs(*sign, Natural::from_owned_limbs_asc(y))
293 } else {
294 unreachable!()
295 }
296}
297
298// Computes `y ~ exp(p / 2^r)` to precision `prec`, within 1 ulp, for `|p / 2^r| < 1`, using up to
299// `2^m` terms of the Taylor series summed by binary splitting. With `P(a,b) = p` if `a+1=b` else
300// `P(a,c)*P(c,b)`, `Q(a,b) = a*2^r` if `a+1=b` (except `Q(0,1)=1`) else `Q(a,c)*Q(c,b)`, and
301// `T(a,b) = P(a,b)` if `a+1=b` else `Q(c,b)*T(a,c) + P(a,c)*T(c,b)`, one has `exp(p/2^r) ~
302// T(0,i)/Q(0,i)`. Since `P(a,b) = p^(b-a)` and only `b-a = 2^j` occur, only the powers `p^(2^j)`
303// (the `ptoj` array) are precomputed; and since `Q(a,b)` is divisible by `2^(r*(b-a-1))`, that
304// power of two is tracked separately rather than stored.
305//
306// This is `mpfr_exp_rational` from `exp3.c`, MPFR 4.2.2.
307fn exp_rational(p: Integer, mut r: i64, m: usize, prec: u64) -> Float {
308 // Normalize p (strip trailing zeros); since |p/2^r| < 1 and p != 0, r stays >= 1.
309 let nz = p.trailing_zeros().unwrap();
310 let p = p >> nz;
311 r -= i64::exact_from(nz);
312 let scratch_len = m + 1;
313 let mut scratch = vec![Integer::ZERO; 3 * scratch_len];
314 split_into_chunks_mut!(scratch, scratch_len, [q, s], ptoj); // ptoj[k] = p^(2^k)
315 let mut scratch = vec![0u64; scratch_len << 1];
316 // P[k]/Q[k] for the remaining terms is <= 2^(-mult[k])
317 let (mult, log2_nb_terms) = scratch.split_at_mut(scratch_len);
318 ptoj[0] = p;
319 for k in 1..m {
320 ptoj[k] = (&ptoj[k - 1]).square();
321 }
322 q[0] = Integer::ONE;
323 s[0] = Integer::ONE;
324 let mut k = 0usize;
325 let mut prec_i_have: u64 = 0;
326 // Main loop: Q[0]*Q[1]*...*Q[k] equals i! as an invariant.
327 let n_terms = u64::power_of_2(u64::exact_from(m));
328 let mut i = 1u64;
329 while prec_i_have < prec && i < n_terms {
330 k += 1;
331 log2_nb_terms[k] = 0; // 1 term
332 q[k] = Integer::from(i + 1);
333 s[k] = Integer::from(i + 1);
334 let mut j = i + 1; // terms computed so far
335 let mut l = 0u32;
336 while j.even() {
337 // Combine and reduce: S[k] covers 2^l consecutive terms.
338 s[k] *= &ptoj[l as usize];
339 let mut t = &s[k - 1] * &q[k];
340 // Q[k] lacks the 2^(r*2^l) factor, so multiply it in when merging.
341 t <<= r << l;
342 t += &s[k];
343 s[k - 1] = t;
344 let (q_lo, q_hi) = q.split_at_mut(k);
345 *q_lo.last_mut().unwrap() *= &q_hi[0];
346 log2_nb_terms[k - 1] += 1;
347 prec_i_have = q[k].significant_bits();
348 let prec_ptoj = ptoj[l as usize].significant_bits();
349 mult[k - 1].wrapping_add_assign(
350 prec_i_have
351 .wrapping_add(u64::wrapping_from(r << l))
352 .wrapping_sub(prec_ptoj)
353 .wrapping_sub(1),
354 );
355 prec_i_have = mult[k - 1];
356 mult[k] = mult[k - 1];
357 l += 1;
358 j >>= 1;
359 k -= 1;
360 }
361 i += 1;
362 }
363 // Accumulate all products into S[0] and Q[0].
364 let mut h = 0u64; // accumulated terms in the right part S[k]/Q[k]
365 while k > 0 {
366 let jj = log2_nb_terms[k - 1] as usize;
367 s[k] *= &ptoj[jj];
368 let mut t = &s[k - 1] * &q[k];
369 h += u64::power_of_2(log2_nb_terms[k]);
370 t <<= r * i64::exact_from(h);
371 t += &s[k];
372 s[k - 1] = t;
373 let (q_lo, q_hi) = q.split_at_mut(k);
374 *q_lo.last_mut().unwrap() *= &q_hi[0];
375 k -= 1;
376 }
377 // Q[0] now equals i!. Scale S[0] to ~2*prec bits and Q[0] to ~prec bits, then divide.
378 let mut s0 = core::mem::replace(&mut s[0], Integer::ZERO);
379 let mut q0 = core::mem::replace(&mut q[0], Integer::ZERO);
380 let mut diff = i64::exact_from(s0.significant_bits()) - (i64::exact_from(prec) << 1);
381 let mut expo = diff;
382 s0 >>= diff; // negative shift is a left shift, covering MPFR's mul_2exp branch
383 diff = i64::exact_from(q0.significant_bits()) - i64::exact_from(prec);
384 expo -= diff;
385 q0 >>= diff;
386 s0 /= q0; // truncating division (both positive)
387 // y = (S[0] rounded to prec) * 2^(expo - r*(i-1)); MPFR sets the mantissa via set_z then
388 // overrides the exponent, which is exactly this scaling. A direct `from_integer_prec_round(s0,
389 // ..)` would pass through the intermediate exponent sb(s0) ~ 2 * prec, which exceeds
390 // MAX_EXPONENT once prec approaches it (malachite's precision range exceeds its exponent range,
391 // unlike MPFR's, whose emax dwarfs any practical precision) and would silently saturate at the
392 // largest finite value. Attaching the scaling before the conversion keeps the exponent in
393 // range: the scaled value is a factor of exp(chunk), of ordinary size.
394 Float::from_rational_prec_round(
395 Rational::from(s0) << (expo - r * (i64::exact_from(i) - 1)),
396 prec,
397 Floor,
398 )
399 .0
400}
401
402// Computes `exp(x)` rounded to precision `precy` with rounding mode `rm`. Decomposes `x` into
403// limb-window chunks (`extract`), exponentiates each chunk's contribution with binary splitting
404// (`exp_rational`), and multiplies them, using O(M(n) log(n)^2) for high precision.
405//
406// This is `mpfr_exp_3` from `exp3.c`, MPFR 4.2.2.
407pub(crate) fn exp_3(x: &Float, precy: u64, rm: RoundingMode) -> (Float, Ordering) {
408 const SHIFT: u64 = Limb::WIDTH >> 1;
409 // prec_x: number of chunk levels, ~log2 of x's limb count.
410 let prec_x = x
411 .get_prec()
412 .unwrap()
413 .ceiling_log_base_2()
414 .saturating_sub(Limb::LOG_WIDTH);
415 let mut ttt = i64::from(x.get_exponent().unwrap());
416 let mut x_copy = x.clone();
417 let shift_x = if ttt > 0 {
418 // Shift x down to magnitude < 1.
419 let s = u64::exact_from(ttt);
420 x_copy = x >> s;
421 ttt = i64::from(x_copy.get_exponent().unwrap());
422 s
423 } else {
424 0
425 };
426 debug_assert!(ttt <= 0);
427 let mut realprec = precy + (prec_x + precy).ceiling_log_base_2();
428 let mut prec = realprec + SHIFT + 2 + shift_x;
429 let mut increment = Limb::WIDTH;
430 loop {
431 let k = prec.ceiling_log_base_2().saturating_sub(Limb::LOG_WIDTH);
432 let mut twopoweri = Limb::WIDTH;
433 // Particular case i = 0.
434 let uk = extract(&x_copy, 0);
435 debug_assert_ne!(uk, 0);
436 let mut tmp = exp_rational(
437 uk,
438 i64::exact_from(SHIFT + twopoweri) - ttt,
439 usize::exact_from(k + 1),
440 prec,
441 );
442 for _ in 0..SHIFT {
443 tmp.square_prec_round_assign(prec, Floor);
444 }
445 twopoweri <<= 1;
446 // General case.
447 let iter = k.min(prec_x);
448 for i in 1..=iter {
449 let uk = extract(&x_copy, i);
450 if uk != 0 {
451 let t = exp_rational(
452 uk,
453 i64::exact_from(twopoweri) - ttt,
454 usize::exact_from(k - i + 1),
455 prec,
456 );
457 tmp.mul_prec_round_assign(t, prec, Floor);
458 }
459 twopoweri <<= 1;
460 }
461 // Raise tmp to 2^shift_x to undo the initial down-shift of x; detect over/underflow.
462 let (val, scaled) = if shift_x > 0 {
463 for _ in 0..shift_x - 1 {
464 tmp.square_prec_round_assign(prec, Floor);
465 }
466 let mut t = tmp.square_prec_round_ref(prec, Floor).0;
467 if t.is_infinite() {
468 // Unreachable: `normal_ref` decides the overflow boundary exactly, so here exp(x) <
469 // 2^emax, every Floor-rounded intermediate lies below its true value, and no
470 // squaring can overflow. (Even if one somehow did, Floor rounding saturates at the
471 // largest finite value rather than reaching infinity.)
472 fail_on_untested_path("exp_3, overflow above normal_ref's bound_emax");
473 return exp_overflow(precy, rm);
474 }
475 let mut scaled = false;
476 if matches!(t.0, Zero { .. }) {
477 // Possibly spurious underflow: rescale by 2 and retry. Reachable only for x in the
478 // narrow band just above `normal_ref`'s `bound_emin`; exp's own test inputs never
479 // land there, but `Float::pow`'s do (its Ziv loop feeds y * ln|x| here at boundary
480 // magnitudes), and pow's property tests validate this path against MPFR.
481 tmp <<= 1;
482 t = tmp.square_prec_round_ref(prec, Floor).0;
483 if matches!(t.0, Zero { .. }) {
484 // exact result < 2^(emin - 2): genuine underflow.
485 return exp_underflow(precy, if rm == Nearest { Down } else { rm });
486 }
487 scaled = true;
488 }
489 (t, scaled)
490 } else {
491 (tmp, false)
492 };
493 if float_can_round(val.significand_ref().unwrap(), realprec, precy, rm) {
494 let mut y = val;
495 let mut inexact = y.set_prec_round(precy, rm);
496 if scaled && y.is_normal() {
497 // Undo the *2 scaling: y /= 4.
498 let ey = i64::from(y.get_exponent().unwrap());
499 let inex2 = y.shr_round_assign(2, rm);
500 if inex2 != Equal {
501 // Underflow while unscaling.
502 if rm == Nearest
503 && inexact == Less
504 && matches!(y.0, Zero { .. })
505 && ey == Float::MIN_EXPONENT_PLUS_1_I64
506 {
507 // Double rounding: RNDN rounded the scaled result down to 2^emin, but the
508 // exact result is > 2^(emin - 2), so round up instead.
509 (y, inexact) = (Float::min_positive_value_prec(precy), Greater);
510 } else {
511 inexact = inex2;
512 }
513 }
514 }
515 return (y, inexact);
516 }
517 realprec += increment;
518 increment = realprec >> 1;
519 prec = realprec + SHIFT + 2 + shift_x;
520 }
521}
522
523// Computes `exp(x)` rounded to precision `precy` with rounding mode `rm`, returning the rounded
524// value and an [`Ordering`] comparing it to the exact result. `x` must be finite and nonzero and
525// `exp(x)` must be in range; the dispatcher (`exp`) guarantees both. Uses Brent's method: `exp(x) =
526// (1 + r + r^2/2! + ...)^(2^K) * 2^n` with `x = n*log(2) + 2^K*r`.
527//
528// Below `EXP_2_THRESHOLD` the naive series (`exp2_aux`) is used with the square-root `K`; at or
529// above it the Paterson-Stockmeyer series (`exp2_aux2`) is used with the cube-root `K`.
530//
531// This is `mpfr_exp_2` from `exp_2.c`, MPFR 4.2.2.
532pub(crate) fn exp_2(x: &Float, precy: u64, rm: RoundingMode) -> (Float, Ordering) {
533 let expx = i64::from(x.get_exponent().unwrap());
534 // Argument reduction: n ~ round(x / log(2)) (need not be exact).
535 let mut n: i64 = if expx <= -2 {
536 // |x| <= 0.25, so n = 0
537 0
538 } else {
539 let log2_est = Float::ln_2_prec_round(WIDTH_MINUS_1, Down).0;
540 let r_est = x.div_prec_ref_val(log2_est, WIDTH_MINUS_1).0;
541 i64::rounding_from(r_est, Nearest).0
542 };
543 // error_r bounds the bits cancelled in x - n*log(2)
544 let error_r: u64 = if n == 0 {
545 0
546 } else {
547 (n.unsigned_abs() + 1).significant_bits()
548 };
549 // Working-precision setup. Square-root K for the naive series, cube-root K for
550 // Paterson-Stockmeyer.
551 let k_param = if precy < EXP_2_THRESHOLD {
552 precy.div_ceil(2).floor_sqrt() + 3
553 } else {
554 (precy << 2).floor_root(3)
555 };
556 let l = (precy - 1) / k_param + 1;
557 let mut err = k_param + ((l << 1) + 18).ceiling_log_base_2();
558 let mut q = precy + err + k_param + 10;
559 // if |x| >> 1, account for the cancelled bits
560 if expx > 0 {
561 q += u64::exact_from(expx);
562 }
563 let mut increment = Limb::WIDTH;
564 loop {
565 let working = q + error_r;
566 // s is within 1 ulp of log(2), rounded so that r = x - n*log(2) is bounded above.
567 let s = Float::ln_2_prec_round(working, if n >= 0 { Down } else { Up }).0;
568 // r = |n| * log(2) (directed); negate when n < 0, so r <= n*log(2) within 3 ulps.
569 let mut r = s
570 .mul_prec_round_ref_val(
571 Float::from(n.unsigned_abs()),
572 working,
573 if n >= 0 { Down } else { Up },
574 )
575 .0;
576 if n < 0 {
577 r.neg_assign();
578 }
579 r = x.sub_prec_round_ref_val(r, working, Up).0;
580 // if the initial n was too large, r came out negative: reduce n
581 while r.is_normal() && r.is_sign_negative() {
582 n -= 1;
583 r.add_prec_round_assign_ref(&s, working, Up);
584 }
585 // if r is 0 we cannot round correctly; otherwise sum the series
586 if r.is_normal() {
587 // the cancelled low error_r bits of r are non-significant, so drop them
588 if error_r > 0 {
589 r.set_prec_round(q, Up);
590 }
591 // r = (x - n*log(2)) / 2^K, exact
592 r >>= k_param;
593 // ss <- 1 + r + r^2/2! + ... (naive method below the threshold, Paterson-Stockmeyer at
594 // or above it)
595 let (mut ss, mut exps, l_err) = if precy < EXP_2_THRESHOLD {
596 exp2_aux(r, q)
597 } else {
598 exp2_aux2(r, q)
599 };
600 // raise to the 2^K power by K squarings
601 for _ in 0..k_param {
602 ss.square_assign();
603 exps <<= 1;
604 let (ss2, sh) = mpz_normalize(ss, i64::exact_from(q));
605 ss = ss2;
606 exps += sh;
607 }
608 // s = ss * 2^exps (exact: ss has at most q bits and working >= q)
609 let s = Float::from_integer_prec(ss, working).0 << exps;
610 // error is at most 2^K * l_err, plus 2 for the 3-ulp error on r
611 err = k_param + l_err.ceiling_log_base_2() + 2;
612 if float_can_round(s.significand_ref().unwrap(), q - err, precy, rm) {
613 // y = s * 2^n, rounded to precy. `float_can_round` only returns true when s's
614 // trusted bits below precy are not all equal, i.e. s is not exactly representable
615 // at precy; since `shl_prec_round` rounds those same bits, it cannot come out Equal
616 // here. (This matches MPFR, which rounds and breaks with no special case -- exp of
617 // a finite nonzero value is irrational, never exactly representable.)
618 return s.shl_prec_round(n, precy, rm);
619 }
620 }
621 // If `r` is not normal it is 0: the rounded x - n*log(2) cancelled exactly, which happens
622 // iff x equals the working-precision rounding of n*log(2). The series can't be summed (it
623 // needs `r != 0`), so fall through to raise `q`; the higher-precision log(2) no longer
624 // rounds to x, so `r != 0` next time. This is MPFR's `MPFR_IS_ZERO(r)` case.
625 q += increment;
626 increment = q >> 1;
627 }
628}
629
630// The overflow result of exp (the value, which is positive, exceeds the maximum finite Float).
631//
632// This is `mpfr_overflow` (with positive sign) as used by `mpfr_exp`, MPFR 4.2.2.
633pub(crate) fn exp_overflow(precy: u64, rm: RoundingMode) -> (Float, Ordering) {
634 match rm {
635 Nearest | Up | Ceiling => (Float::INFINITY, Greater),
636 Down | Floor => (Float::max_finite_value_with_prec(precy), Less),
637 Exact => panic!("exp: Exact rounding was requested, but the result overflows"),
638 }
639}
640
641// The underflow result of exp (the value, which is positive, is below the minimum positive Float).
642// MPFR maps Nearest to toward-zero here, so Nearest joins Down/Floor.
643//
644// This is `mpfr_underflow` (with positive sign) as used by `mpfr_exp`, MPFR 4.2.2.
645pub(crate) fn exp_underflow(precy: u64, rm: RoundingMode) -> (Float, Ordering) {
646 match rm {
647 Nearest | Down | Floor => (Float::ZERO, Less),
648 Up | Ceiling => (Float::min_positive_value_prec(precy), Greater),
649 Exact => panic!("exp: Exact rounding was requested, but the result underflows"),
650 }
651}
652
653// Computes `exp(x)` for finite nonzero `x`, rounded to precision `precy` with rounding mode `rm`.
654// Detects overflow/underflow against `log(2)`-scaled exponent bounds, takes a fast path for tiny
655// `x` (where `exp(x) = 1 +/- ulp(1)`), and otherwise dispatches to `exp_2` (below `EXP_THRESHOLD`)
656// or the binary-splitting `exp_3` (at or above it).
657//
658// This is the finite-nonzero branch of `mpfr_exp` from `exp.c`, MPFR 4.2.2.
659fn exp_prec_round_normal_ref(x: &Float, precy: u64, rm: RoundingMode) -> (Float, Ordering) {
660 // exp of a finite nonzero value is transcendental, hence never exactly representable.
661 assert_ne!(rm, Exact, "Inexact exp");
662 // Overflow/underflow bounds, as ~64-bit Floats. Directed rounding makes `bound_emax` an upper
663 // bound on emax*log(2) and `bound_emin` a lower bound on (emin - 2)*log(2), so the comparisons
664 // below are sound one-sided tests.
665 const BP: u64 = 64;
666 const MAX_EXPONENT_FLOAT: Float = Float::const_from_signed(Float::MAX_EXPONENT as SignedLimb);
667 let (log2_lo, log2_hi) = floor_and_ceiling(Float::ln_2_prec_round(BP, Floor));
668 let bound_emax = log2_hi.mul_prec_round_ref_val(MAX_EXPONENT_FLOAT, BP, Up).0;
669 if *x >= bound_emax {
670 // x > log(2^emax), so exp(x) > 2^emax
671 return exp_overflow(precy, rm);
672 }
673 // `bound_emax` is an upper bound with ~2^-33 of slack, so an x just below it may still
674 // overflow. That sliver must be decided here: below the threshold, every intermediate in
675 // `exp_2` and `exp_3` stays under 2^emax, but a true overflow inside `exp_3` would saturate its
676 // Floor-rounded final squarings at the largest finite value instead of reaching infinity, and
677 // the saturated all-ones significand is one that `float_can_round` never certifies -- the Ziv
678 // loop would grow forever. Decide the sliver exactly, by comparing x with brackets of emax *
679 // log(2) as exact Rationals at widening precision; x is dyadic and the threshold is irrational,
680 // so the comparison always resolves. This mirrors the role of MPFR's overflow flag, which lets
681 // mpfr_exp detect the overflow after the fact.
682 let bound_emax_lo = log2_lo
683 .mul_prec_round_ref_val(MAX_EXPONENT_FLOAT, BP, Floor)
684 .0;
685 if *x >= bound_emax_lo {
686 let xr = Rational::exact_from(x);
687 let emax_r = Rational::from(Float::MAX_EXPONENT);
688 let mut p = 128;
689 loop {
690 let lo = Rational::exact_from(Float::ln_2_prec_round(p, Floor).0) * &emax_r;
691 if xr < lo {
692 break;
693 }
694 let hi = Rational::exact_from(Float::ln_2_prec_round(p, Ceiling).0) * &emax_r;
695 if xr >= hi {
696 // x > emax * log(2), so exp(x) > 2^emax
697 return exp_overflow(precy, rm);
698 }
699 p <<= 1;
700 }
701 }
702 let bound_emin = log2_hi
703 .mul_prec_round(
704 const { Float::const_from_signed((Float::MIN_EXPONENT as SignedLimb) - 2) },
705 BP,
706 Floor,
707 )
708 .0;
709 if *x <= bound_emin {
710 // x < log(2^(emin - 2)), so exp(x) < 2^(emin - 2)
711 return exp_underflow(precy, rm);
712 }
713 let expx = i64::from(x.get_exponent().unwrap());
714 // tiny x: if x < 2^(-precy), then exp(x) = 1 +/- ulp(1)
715 if expx < 0 && u64::exact_from(-expx) > precy {
716 return if x.is_sign_negative() && (rm == Down || rm == Floor) {
717 (one_neighbor(precy, false), Less) // 1 - ulp
718 } else if x.is_sign_positive() && (rm == Up || rm == Ceiling) {
719 (one_neighbor(precy, true), Greater) // 1 + ulp
720 } else {
721 (
722 Float::one_prec(precy),
723 if x.is_sign_positive() { Less } else { Greater },
724 )
725 };
726 }
727 if precy >= EXP_THRESHOLD {
728 exp_3(x, precy, rm)
729 } else {
730 exp_2(x, precy, rm)
731 }
732}
733
734// The neighbor of 1 at precision `prec`: the successor `1 + 2 ^ (1 - prec)` if `above`, otherwise
735// the predecessor `1 - 2 ^ (-prec)`. Both are exactly representable at precision `prec`. (Note that
736// `Float::increment`/`decrement` cannot be used here: they keep the ulp of the current binade, so
737// they bump the precision when crossing into the next binade and overshoot the true predecessor.
738// Also note that the significand cannot be built as a `Natural` and shifted into place: the
739// unshifted intermediate has exponent `prec`, which overflows to infinity when `prec` exceeds
740// `MAX_EXPONENT`, even though the final value's exponent is 0 or 1. Going through a `Rational`
741// keeps every intermediate exponent small. The `i64` conversion fails only for `prec >= 2^63`,
742// where a `Float` of that precision could not be materialized at all.)
743pub(crate) fn one_neighbor(prec: u64, above: bool) -> Float {
744 let p = i64::exact_from(prec);
745 Float::from_rational_prec_round(
746 if above {
747 Rational::ONE + Rational::power_of_2(1 - p)
748 } else {
749 Rational::ONE - Rational::power_of_2(-p)
750 },
751 prec,
752 Exact,
753 )
754 .0
755}
756
757// Computes `exp(x)` for a nonzero `Rational` `x` with `|x| < 1`, by summing its Taylor series
758// `exp(x) = sum x^k / k!`. Used when `x` is too small to be represented as a normal `Float` (so the
759// squeeze in `exp_rational_helper` cannot bracket it), in which case `exp(x)` is very close to 1
760// but may still be more than one ulp away from 1 when `prec` is enormous. The series is summed term
761// by term, bracketing the exact value between two rationals (consecutive partial sums for `x < 0`,
762// a partial sum and a remainder bound for `x > 0`) until both ends round to the same `Float`.
763// Working entirely with values near 1, this avoids ever representing `x` itself as a `Float`.
764pub(crate) fn exp_rational_near_one(
765 x: &Rational,
766 prec: u64,
767 rm: RoundingMode,
768) -> (Float, Ordering) {
769 let negative = x.sign() == Less;
770 let mut s = Rational::ONE; // partial sum S_{k-1}
771 let mut term = Rational::ONE; // x^(k-1) / (k-1)!
772 let mut k = 1u64;
773 loop {
774 term *= x;
775 term /= Rational::from(k); // term = x^k / k!
776 let s_next = &s + &term; // S_k
777 let (lo, hi) = if negative {
778 // The terms alternate in sign with strictly decreasing magnitude (|x| / (k + 1) < 1),
779 // so exp(x) lies between consecutive partial sums.
780 if s < s_next {
781 (s.clone(), s_next.clone())
782 } else {
783 (s_next.clone(), s.clone())
784 }
785 } else {
786 // Every term is positive, so S_k < exp(x), and the remainder is bounded by t_{k+1} / (1
787 // - x).
788 let next = (&term * x) / Rational::from(k + 1); // t_{k+1}
789 (s_next.clone(), &s_next + next / (Rational::ONE - x))
790 };
791 s = s_next;
792 k += 1;
793 let (f_lo, mut o_lo) = Float::from_rational_prec_round_ref(&lo, prec, rm);
794 let (f_hi, mut o_hi) = Float::from_rational_prec_round_ref(&hi, prec, rm);
795 // A bound that is exactly representable at `prec` rounds with `Equal`; treat it as agreeing
796 // with the other bound. (`hi == 1` triggers this for small negative x, since 1 is exact;
797 // the `lo` case only arises when a partial sum lands exactly on a `prec`-bit Float, which
798 // needs an enormous `prec`.)
799 if o_lo == Equal {
800 o_lo = o_hi;
801 }
802 if o_hi == Equal {
803 o_hi = o_lo;
804 }
805 if o_lo == o_hi && f_lo == f_hi {
806 return (f_lo, o_lo);
807 }
808 }
809}
810
811// Computes `exp(x)` for a nonzero `Rational` `x`, rounded to precision `prec` with rounding mode
812// `rm`. (`exp(0) = 1` is handled by the caller.) Because the exponential of a nonzero rational is
813// transcendental, the result is never exactly representable, so `rm` must not be `Exact`.
814fn exp_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
815 assert_ne!(rm, Exact, "Inexact exp");
816 let positive = x.sign() == Greater;
817 let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
818 // x is too small to be represented as a normal Float (|x| < 2^MIN_EXPONENT). The squeeze below
819 // cannot bracket it (its Float bounds would be 0 or out of range), so sum the Taylor series
820 // instead. exp(x) is near 1 but, for an enormous `prec`, possibly more than one ulp away.
821 if exp_x <= Float::MIN_EXPONENT_I64 {
822 return exp_rational_near_one(x, prec, rm);
823 }
824 // Tiny x: if |x| < 2^(-prec-1) then exp(x) is within half an ulp of 1, so it rounds to 1 (or,
825 // for directed rounding away from 1, to the neighbor of 1). This mirrors exp's tiny-x fast
826 // path.
827 if -exp_x > i64::exact_from(prec) {
828 return match (positive, rm) {
829 (false, Down | Floor) => (one_neighbor(prec, false), Less), // 1 - ulp
830 (true, Up | Ceiling) => (one_neighbor(prec, true), Greater), // 1 + ulp
831 (true, _) => (Float::one_prec(prec), Less),
832 (false, _) => (Float::one_prec(prec), Greater),
833 };
834 }
835 // |x| is too large to be a finite Float, so exp(x) overflows (x > 0) or underflows (x < 0).
836 // Smaller x that still overflow/underflow exp are caught by `exp_prec_round_normal_ref` in the
837 // loop below.
838 if exp_x >= Float::MAX_EXPONENT_I64 {
839 return if positive {
840 exp_overflow(prec, rm)
841 } else {
842 exp_underflow(prec, rm)
843 };
844 }
845 // General case: bracket x between the Floats x_lo <= x <= x_hi, exponentiate both, and increase
846 // the working precision until the two bounds round to the same result. exp is monotonic, so
847 // once the bounds agree the exact exp(x) (which lies between them) rounds the same way.
848 let mut working_prec = prec + 10;
849 let mut increment = Limb::WIDTH;
850 loop {
851 let (x_lo, x_o) = Float::from_rational_prec_round_ref(x, working_prec, Floor);
852 if x_o == Equal {
853 // x is exactly representable at `working_prec`, so exp(x) is simply exp(x_lo).
854 return exp_prec_round_normal_ref(&x_lo, prec, rm);
855 }
856 let (x_lo, x_hi) = floor_and_ceiling((x_lo, x_o));
857 // exp of a finite nonzero Float is transcendental, so `exp_prec_round_normal_ref` is never
858 // exact: both orderings are `Less` or `Greater`, never `Equal`.
859 let (e_lo, o_lo) = exp_prec_round_normal_ref(&x_lo, prec, rm);
860 let (e_hi, o_hi) = exp_prec_round_normal_ref(&x_hi, prec, rm);
861 if o_lo == o_hi && e_lo == e_hi {
862 return (e_lo, o_lo);
863 }
864 working_prec += increment;
865 increment = working_prec >> 1;
866 }
867}
868
869impl Float {
870 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the specified
871 /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
872 /// [`Ordering`] is also returned, indicating whether the rounded exponential is less than,
873 /// equal to, or greater than the exact exponential. Although `NaN`s are not comparable to any
874 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
875 ///
876 /// See [`RoundingMode`] for a description of the possible rounding modes.
877 ///
878 /// $$
879 /// f(x,p,m) = e^x+\varepsilon.
880 /// $$
881 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
882 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
883 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
884 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
885 /// 2^{\lfloor\log_2 e^x\rfloor-p}$.
886 ///
887 /// If the output has a precision, it is `prec`.
888 ///
889 /// Special cases:
890 /// - $f(\text{NaN},p,m)=\text{NaN}$
891 /// - $f(\infty,p,m)=\infty$
892 /// - $f(-\infty,p,m)=0.0$
893 /// - $f(\pm0.0,p,m)=1.0$
894 ///
895 /// Overflow and underflow:
896 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
897 /// returned instead.
898 /// - 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
899 /// returned instead.
900 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
901 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
902 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
903 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
904 /// instead.
905 ///
906 /// If you know you'll be using `Nearest`, consider using [`Float::exp_prec`] instead. If you
907 /// know that your target precision is the precision of the input, consider using
908 /// [`Float::exp_round`] instead. If both of these things are true, consider using
909 /// [`Float::exp`] instead.
910 ///
911 /// # Worst-case complexity
912 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
913 ///
914 /// $M(n, m) = O(n \log n + m)$
915 ///
916 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
917 /// `self.significant_bits()`.
918 ///
919 /// # Panics
920 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
921 /// precision.
922 ///
923 /// # Examples
924 /// ```
925 /// use malachite_base::rounding_modes::RoundingMode::*;
926 /// use malachite_float::Float;
927 /// use std::cmp::Ordering::*;
928 ///
929 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
930 /// .0
931 /// .exp_prec_round(5, Floor);
932 /// assert_eq!(e.to_string(), "2.62");
933 /// assert_eq!(o, Less);
934 ///
935 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
936 /// .0
937 /// .exp_prec_round(5, Ceiling);
938 /// assert_eq!(e.to_string(), "2.75");
939 /// assert_eq!(o, Greater);
940 ///
941 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
942 /// .0
943 /// .exp_prec_round(5, Nearest);
944 /// assert_eq!(e.to_string(), "2.75");
945 /// assert_eq!(o, Greater);
946 ///
947 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
948 /// .0
949 /// .exp_prec_round(20, Floor);
950 /// assert_eq!(e.to_string(), "2.7182808");
951 /// assert_eq!(o, Less);
952 ///
953 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
954 /// .0
955 /// .exp_prec_round(20, Ceiling);
956 /// assert_eq!(e.to_string(), "2.7182846");
957 /// assert_eq!(o, Greater);
958 ///
959 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
960 /// .0
961 /// .exp_prec_round(20, Nearest);
962 /// assert_eq!(e.to_string(), "2.7182808");
963 /// assert_eq!(o, Less);
964 /// ```
965 #[inline]
966 pub fn exp_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
967 self.exp_prec_round_ref(prec, rm)
968 }
969
970 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the specified
971 /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
972 /// [`Ordering`] is also returned, indicating whether the rounded exponential is less than,
973 /// equal to, or greater than the exact exponential. Although `NaN`s are not comparable to any
974 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
975 ///
976 /// See [`RoundingMode`] for a description of the possible rounding modes.
977 ///
978 /// $$
979 /// f(x,p,m) = e^x+\varepsilon.
980 /// $$
981 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
982 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
983 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
984 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
985 /// 2^{\lfloor\log_2 e^x\rfloor-p}$.
986 ///
987 /// If the output has a precision, it is `prec`.
988 ///
989 /// Special cases:
990 /// - $f(\text{NaN},p,m)=\text{NaN}$
991 /// - $f(\infty,p,m)=\infty$
992 /// - $f(-\infty,p,m)=0.0$
993 /// - $f(\pm0.0,p,m)=1.0$
994 ///
995 /// Overflow and underflow:
996 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
997 /// returned instead.
998 /// - 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
999 /// returned instead.
1000 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1001 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1002 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1003 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1004 /// instead.
1005 ///
1006 /// If you know you'll be using `Nearest`, consider using [`Float::exp_prec_ref`] instead. If
1007 /// you know that your target precision is the precision of the input, consider using
1008 /// [`Float::exp_round_ref`] instead. If both of these things are true, consider using
1009 /// `(&Float).exp()` instead.
1010 ///
1011 /// # Worst-case complexity
1012 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1013 ///
1014 /// $M(n, m) = O(n \log n + m)$
1015 ///
1016 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1017 /// `self.significant_bits()`.
1018 ///
1019 /// # Panics
1020 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1021 /// precision.
1022 ///
1023 /// # Examples
1024 /// ```
1025 /// use malachite_base::rounding_modes::RoundingMode::*;
1026 /// use malachite_float::Float;
1027 /// use std::cmp::Ordering::*;
1028 ///
1029 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1030 /// .0
1031 /// .exp_prec_round_ref(5, Floor);
1032 /// assert_eq!(e.to_string(), "2.62");
1033 /// assert_eq!(o, Less);
1034 ///
1035 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1036 /// .0
1037 /// .exp_prec_round_ref(5, Ceiling);
1038 /// assert_eq!(e.to_string(), "2.75");
1039 /// assert_eq!(o, Greater);
1040 ///
1041 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1042 /// .0
1043 /// .exp_prec_round_ref(5, Nearest);
1044 /// assert_eq!(e.to_string(), "2.75");
1045 /// assert_eq!(o, Greater);
1046 ///
1047 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1048 /// .0
1049 /// .exp_prec_round_ref(20, Floor);
1050 /// assert_eq!(e.to_string(), "2.7182808");
1051 /// assert_eq!(o, Less);
1052 ///
1053 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1054 /// .0
1055 /// .exp_prec_round_ref(20, Ceiling);
1056 /// assert_eq!(e.to_string(), "2.7182846");
1057 /// assert_eq!(o, Greater);
1058 ///
1059 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1060 /// .0
1061 /// .exp_prec_round_ref(20, Nearest);
1062 /// assert_eq!(e.to_string(), "2.7182808");
1063 /// assert_eq!(o, Less);
1064 /// ```
1065 pub fn exp_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1066 assert_ne!(prec, 0);
1067 match &self.0 {
1068 NaN => (Self::NAN, Equal),
1069 // exp(+inf) = +inf; exp(-inf) = +0
1070 Infinity { sign } => {
1071 if *sign {
1072 (Self::INFINITY, Equal)
1073 } else {
1074 (Self::ZERO, Equal)
1075 }
1076 }
1077 // exp(+0) = exp(-0) = 1
1078 Zero { .. } => (Self::one_prec(prec), Equal),
1079 Finite { .. } => exp_prec_round_normal_ref(self, prec, rm),
1080 }
1081 }
1082
1083 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the nearest value of
1084 /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
1085 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1086 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1087 /// returns a `NaN` it also returns `Equal`.
1088 ///
1089 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1090 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1091 /// description of the `Nearest` rounding mode.
1092 ///
1093 /// $$
1094 /// f(x,p) = e^x+\varepsilon.
1095 /// $$
1096 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1097 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1098 ///
1099 /// If the output has a precision, it is `prec`.
1100 ///
1101 /// Special cases:
1102 /// - $f(\text{NaN},p)=\text{NaN}$
1103 /// - $f(\infty,p)=\infty$
1104 /// - $f(-\infty,p)=0.0$
1105 /// - $f(\pm0.0,p)=1.0$
1106 ///
1107 /// Overflow and underflow:
1108 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1109 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1110 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1111 ///
1112 /// If you want to use a rounding mode other than `Nearest`, consider using
1113 /// [`Float::exp_prec_round`] instead. If you know that your target precision is the precision
1114 /// of the input, consider using [`Float::exp`] instead.
1115 ///
1116 /// # Worst-case complexity
1117 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1118 ///
1119 /// $M(n, m) = O(n \log n + m)$
1120 ///
1121 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1122 /// `self.significant_bits()`.
1123 ///
1124 /// # Examples
1125 /// ```
1126 /// use malachite_float::Float;
1127 /// use std::cmp::Ordering::*;
1128 ///
1129 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec(5);
1130 /// assert_eq!(e.to_string(), "2.75");
1131 /// assert_eq!(o, Greater);
1132 ///
1133 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec(20);
1134 /// assert_eq!(e.to_string(), "2.7182808");
1135 /// assert_eq!(o, Less);
1136 /// ```
1137 #[inline]
1138 pub fn exp_prec(self, prec: u64) -> (Self, Ordering) {
1139 self.exp_prec_round(prec, Nearest)
1140 }
1141
1142 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the nearest value of
1143 /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
1144 /// returned, indicating whether the rounded exponential is less than, equal to, or greater than
1145 /// the exact exponential. Although `NaN`s are not comparable to any [`Float`], whenever this
1146 /// function returns a `NaN` it also returns `Equal`.
1147 ///
1148 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1149 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1150 /// description of the `Nearest` rounding mode.
1151 ///
1152 /// $$
1153 /// f(x,p) = e^x+\varepsilon.
1154 /// $$
1155 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1156 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1157 ///
1158 /// If the output has a precision, it is `prec`.
1159 ///
1160 /// Special cases:
1161 /// - $f(\text{NaN},p)=\text{NaN}$
1162 /// - $f(\infty,p)=\infty$
1163 /// - $f(-\infty,p)=0.0$
1164 /// - $f(\pm0.0,p)=1.0$
1165 ///
1166 /// Overflow and underflow:
1167 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1168 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1169 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1170 ///
1171 /// If you want to use a rounding mode other than `Nearest`, consider using
1172 /// [`Float::exp_prec_round_ref`] instead. If you know that your target precision is the
1173 /// precision of the input, consider using `(&Float).exp()` instead.
1174 ///
1175 /// # Worst-case complexity
1176 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1177 ///
1178 /// $M(n, m) = O(n \log n + m)$
1179 ///
1180 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1181 /// `self.significant_bits()`.
1182 ///
1183 /// # Examples
1184 /// ```
1185 /// use malachite_float::Float;
1186 /// use std::cmp::Ordering::*;
1187 ///
1188 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec_ref(5);
1189 /// assert_eq!(e.to_string(), "2.75");
1190 /// assert_eq!(o, Greater);
1191 ///
1192 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec_ref(20);
1193 /// assert_eq!(e.to_string(), "2.7182808");
1194 /// assert_eq!(o, Less);
1195 /// ```
1196 #[inline]
1197 pub fn exp_prec_ref(&self, prec: u64) -> (Self, Ordering) {
1198 self.exp_prec_round_ref(prec, Nearest)
1199 }
1200
1201 /// Computes $e^x$, the exponential of a [`Float`], rounding the result with the specified
1202 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
1203 /// whether the rounded exponential is less than, equal to, or greater than the exact
1204 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1205 /// returns a `NaN` it also returns `Equal`.
1206 ///
1207 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1208 /// description of the possible rounding modes.
1209 ///
1210 /// $$
1211 /// f(x,m) = e^x+\varepsilon.
1212 /// $$
1213 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1214 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1215 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1216 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1217 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1218 ///
1219 /// If the output has a precision, it is the precision of the input.
1220 ///
1221 /// Special cases:
1222 /// - $f(\text{NaN},m)=\text{NaN}$
1223 /// - $f(\infty,m)=\infty$
1224 /// - $f(-\infty,m)=0.0$
1225 /// - $f(\pm0.0,m)=1.0$
1226 ///
1227 /// See the [`Float::exp_prec_round`] documentation for information on overflow and underflow.
1228 ///
1229 /// If you want to specify an output precision, consider using [`Float::exp_prec_round`]
1230 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1231 /// [`Float::exp`] instead.
1232 ///
1233 /// # Worst-case complexity
1234 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1235 ///
1236 /// $M(n) = O(n \log n)$
1237 ///
1238 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1239 ///
1240 /// # Panics
1241 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1242 /// precision.
1243 ///
1244 /// # Examples
1245 /// ```
1246 /// use malachite_base::rounding_modes::RoundingMode::*;
1247 /// use malachite_float::Float;
1248 /// use std::cmp::Ordering::*;
1249 ///
1250 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Floor);
1251 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1252 /// assert_eq!(o, Less);
1253 ///
1254 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Ceiling);
1255 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713544");
1256 /// assert_eq!(o, Greater);
1257 ///
1258 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Nearest);
1259 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1260 /// assert_eq!(o, Less);
1261 /// ```
1262 #[inline]
1263 pub fn exp_round(self, rm: RoundingMode) -> (Self, Ordering) {
1264 let prec = self.significant_bits();
1265 self.exp_prec_round(prec, rm)
1266 }
1267
1268 /// Computes $e^x$, the exponential of a [`Float`], rounding the result with the specified
1269 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
1270 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1271 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1272 /// returns a `NaN` it also returns `Equal`.
1273 ///
1274 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1275 /// description of the possible rounding modes.
1276 ///
1277 /// $$
1278 /// f(x,m) = e^x+\varepsilon.
1279 /// $$
1280 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1281 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1282 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1283 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1284 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1285 ///
1286 /// If the output has a precision, it is the precision of the input.
1287 ///
1288 /// Special cases:
1289 /// - $f(\text{NaN},m)=\text{NaN}$
1290 /// - $f(\infty,m)=\infty$
1291 /// - $f(-\infty,m)=0.0$
1292 /// - $f(\pm0.0,m)=1.0$
1293 ///
1294 /// See the [`Float::exp_prec_round`] documentation for information on overflow and underflow.
1295 ///
1296 /// If you want to specify an output precision, consider using [`Float::exp_prec_round_ref`]
1297 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1298 /// `(&Float).exp()` instead.
1299 ///
1300 /// # Worst-case complexity
1301 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1302 ///
1303 /// $M(n) = O(n \log n)$
1304 ///
1305 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1306 ///
1307 /// # Panics
1308 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1309 /// precision.
1310 ///
1311 /// # Examples
1312 /// ```
1313 /// use malachite_base::rounding_modes::RoundingMode::*;
1314 /// use malachite_float::Float;
1315 /// use std::cmp::Ordering::*;
1316 ///
1317 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round_ref(Floor);
1318 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1319 /// assert_eq!(o, Less);
1320 ///
1321 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1322 /// .0
1323 /// .exp_round_ref(Ceiling);
1324 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713544");
1325 /// assert_eq!(o, Greater);
1326 ///
1327 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1328 /// .0
1329 /// .exp_round_ref(Nearest);
1330 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1331 /// assert_eq!(o, Less);
1332 /// ```
1333 #[inline]
1334 pub fn exp_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1335 let prec = self.significant_bits();
1336 self.exp_prec_round_ref(prec, rm)
1337 }
1338
1339 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result to the
1340 /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
1341 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1342 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1343 /// sets the [`Float`] to `NaN` it also returns `Equal`.
1344 ///
1345 /// See [`RoundingMode`] for a description of the possible rounding modes.
1346 ///
1347 /// $$
1348 /// x \gets e^x+\varepsilon.
1349 /// $$
1350 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1351 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1352 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1353 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1354 /// 2^{\lfloor\log_2 e^x\rfloor-p}$.
1355 ///
1356 /// If the output has a precision, it is `prec`.
1357 ///
1358 /// See the [`Float::exp_prec_round`] documentation for information on special cases, overflow,
1359 /// and underflow.
1360 ///
1361 /// If you know you'll be using `Nearest`, consider using [`Float::exp_prec_assign`] instead. If
1362 /// you know that your target precision is the precision of the input, consider using
1363 /// [`Float::exp_round_assign`] instead. If both of these things are true, consider using
1364 /// [`Float::exp_assign`] instead.
1365 ///
1366 /// # Worst-case complexity
1367 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1368 ///
1369 /// $M(n, m) = O(n \log n + m)$
1370 ///
1371 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1372 /// `self.significant_bits()`.
1373 ///
1374 /// # Panics
1375 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1376 /// precision.
1377 ///
1378 /// # Examples
1379 /// ```
1380 /// use malachite_base::rounding_modes::RoundingMode::*;
1381 /// use malachite_float::Float;
1382 /// use std::cmp::Ordering::*;
1383 ///
1384 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1385 /// assert_eq!(x.exp_prec_round_assign(5, Floor), Less);
1386 /// assert_eq!(x.to_string(), "2.62");
1387 ///
1388 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1389 /// assert_eq!(x.exp_prec_round_assign(5, Ceiling), Greater);
1390 /// assert_eq!(x.to_string(), "2.75");
1391 ///
1392 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1393 /// assert_eq!(x.exp_prec_round_assign(5, Nearest), Greater);
1394 /// assert_eq!(x.to_string(), "2.75");
1395 ///
1396 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1397 /// assert_eq!(x.exp_prec_round_assign(20, Floor), Less);
1398 /// assert_eq!(x.to_string(), "2.7182808");
1399 ///
1400 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1401 /// assert_eq!(x.exp_prec_round_assign(20, Ceiling), Greater);
1402 /// assert_eq!(x.to_string(), "2.7182846");
1403 ///
1404 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1405 /// assert_eq!(x.exp_prec_round_assign(20, Nearest), Less);
1406 /// assert_eq!(x.to_string(), "2.7182808");
1407 /// ```
1408 #[inline]
1409 pub fn exp_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1410 let mut x = Self::ZERO;
1411 swap(self, &mut x);
1412 let o;
1413 (*self, o) = x.exp_prec_round(prec, rm);
1414 o
1415 }
1416
1417 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result to the nearest
1418 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
1419 /// rounded exponential is less than, equal to, or greater than the exact exponential. Although
1420 /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
1421 /// `NaN` it also returns `Equal`.
1422 ///
1423 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1424 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1425 /// description of the `Nearest` rounding mode.
1426 ///
1427 /// $$
1428 /// x \gets e^x+\varepsilon.
1429 /// $$
1430 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1431 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1432 ///
1433 /// If the output has a precision, it is `prec`.
1434 ///
1435 /// See the [`Float::exp_prec`] documentation for information on special cases, overflow, and
1436 /// underflow.
1437 ///
1438 /// If you want to use a rounding mode other than `Nearest`, consider using
1439 /// [`Float::exp_prec_round_assign`] instead. If you know that your target precision is the
1440 /// precision of the input, consider using [`Float::exp_assign`] instead.
1441 ///
1442 /// # Worst-case complexity
1443 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m)$
1444 ///
1445 /// $M(n, m) = O(n \log n + m)$
1446 ///
1447 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1448 /// `self.significant_bits()`.
1449 ///
1450 /// # Examples
1451 /// ```
1452 /// use malachite_float::Float;
1453 /// use std::cmp::Ordering::*;
1454 ///
1455 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1456 /// assert_eq!(x.exp_prec_assign(5), Greater);
1457 /// assert_eq!(x.to_string(), "2.75");
1458 ///
1459 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1460 /// assert_eq!(x.exp_prec_assign(20), Less);
1461 /// assert_eq!(x.to_string(), "2.7182808");
1462 /// ```
1463 #[inline]
1464 pub fn exp_prec_assign(&mut self, prec: u64) -> Ordering {
1465 self.exp_prec_round_assign(prec, Nearest)
1466 }
1467
1468 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result with the
1469 /// specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded
1470 /// exponential is less than, equal to, or greater than the exact exponential. Although `NaN`s
1471 /// are not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it
1472 /// also returns `Equal`.
1473 ///
1474 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1475 /// description of the possible rounding modes.
1476 ///
1477 /// $$
1478 /// x \gets e^x+\varepsilon.
1479 /// $$
1480 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1481 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1482 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1483 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1484 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1485 ///
1486 /// If the output has a precision, it is the precision of the input.
1487 ///
1488 /// See the [`Float::exp_round`] documentation for information on special cases, overflow, and
1489 /// underflow.
1490 ///
1491 /// If you want to specify an output precision, consider using [`Float::exp_prec_round_assign`]
1492 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1493 /// [`Float::exp_assign`] instead.
1494 ///
1495 /// # Worst-case complexity
1496 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1497 ///
1498 /// $M(n) = O(n \log n)$
1499 ///
1500 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1501 ///
1502 /// # Panics
1503 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1504 /// precision.
1505 ///
1506 /// # Examples
1507 /// ```
1508 /// use malachite_base::rounding_modes::RoundingMode::*;
1509 /// use malachite_float::Float;
1510 /// use std::cmp::Ordering::*;
1511 ///
1512 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1513 /// assert_eq!(x.exp_round_assign(Floor), Less);
1514 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1515 ///
1516 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1517 /// assert_eq!(x.exp_round_assign(Ceiling), Greater);
1518 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713544");
1519 ///
1520 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1521 /// assert_eq!(x.exp_round_assign(Nearest), Less);
1522 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1523 /// ```
1524 #[inline]
1525 pub fn exp_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1526 let prec = self.significant_bits();
1527 self.exp_prec_round_assign(prec, rm)
1528 }
1529
1530 #[allow(clippy::needless_pass_by_value)]
1531 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the specified
1532 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1533 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1534 /// rounded exponential is less than, equal to, or greater than the exact exponential.
1535 ///
1536 /// See [`RoundingMode`] for a description of the possible rounding modes.
1537 ///
1538 /// $$
1539 /// f(x,p,m) = e^x+\varepsilon.
1540 /// $$
1541 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1542 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$.
1543 ///
1544 /// These bounds do not apply when the result overflows or underflows; see below.
1545 ///
1546 /// The output has precision `prec`.
1547 ///
1548 /// Special cases:
1549 /// - $f(0,p,m)=1$.
1550 ///
1551 /// Overflow and underflow:
1552 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1553 /// returned instead.
1554 /// - 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
1555 /// returned instead.
1556 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1557 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1558 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1559 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1560 /// instead.
1561 ///
1562 /// If you know you'll be using `Nearest`, consider using [`Float::exp_rational_prec`] instead.
1563 ///
1564 /// # Worst-case complexity
1565 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1566 ///
1567 /// $M(n, m) = O(n \log n + m \log m)$
1568 ///
1569 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1570 /// `x.significant_bits()`.
1571 ///
1572 /// # Panics
1573 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1574 /// with the given precision (which is the case for every nonzero input).
1575 ///
1576 /// # Examples
1577 /// ```
1578 /// use malachite_base::rounding_modes::RoundingMode::*;
1579 /// use malachite_float::Float;
1580 /// use malachite_q::Rational;
1581 /// use std::cmp::Ordering::*;
1582 ///
1583 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1584 /// assert_eq!(e.to_string(), "1.81");
1585 /// assert_eq!(o, Less);
1586 ///
1587 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1588 /// assert_eq!(e.to_string(), "1.88");
1589 /// assert_eq!(o, Greater);
1590 ///
1591 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1592 /// assert_eq!(e.to_string(), "1.8221188");
1593 /// assert_eq!(o, Less);
1594 ///
1595 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1596 /// assert_eq!(e.to_string(), "1.8221207");
1597 /// assert_eq!(o, Greater);
1598 /// ```
1599 #[inline]
1600 pub fn exp_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1601 Self::exp_rational_prec_round_ref(&x, prec, rm)
1602 }
1603
1604 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the specified
1605 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1606 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1607 /// rounded exponential is less than, equal to, or greater than the exact exponential.
1608 ///
1609 /// See [`RoundingMode`] for a description of the possible rounding modes.
1610 ///
1611 /// $$
1612 /// f(x,p,m) = e^x+\varepsilon.
1613 /// $$
1614 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1615 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$.
1616 ///
1617 /// These bounds do not apply when the result overflows or underflows; see below.
1618 ///
1619 /// The output has precision `prec`.
1620 ///
1621 /// Special cases:
1622 /// - $f(0,p,m)=1$.
1623 ///
1624 /// Overflow and underflow:
1625 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1626 /// returned instead.
1627 /// - 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
1628 /// returned instead.
1629 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1630 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1631 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1632 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1633 /// instead.
1634 ///
1635 /// If you know you'll be using `Nearest`, consider using [`Float::exp_rational_prec_ref`]
1636 /// instead.
1637 ///
1638 /// # Worst-case complexity
1639 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1640 ///
1641 /// $M(n, m) = O(n \log n + m \log m)$
1642 ///
1643 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1644 /// `x.significant_bits()`.
1645 ///
1646 /// # Panics
1647 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1648 /// with the given precision (which is the case for every nonzero input).
1649 ///
1650 /// # Examples
1651 /// ```
1652 /// use malachite_base::rounding_modes::RoundingMode::*;
1653 /// use malachite_float::Float;
1654 /// use malachite_q::Rational;
1655 /// use std::cmp::Ordering::*;
1656 ///
1657 /// let (e, o) =
1658 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1659 /// assert_eq!(e.to_string(), "1.81");
1660 /// assert_eq!(o, Less);
1661 ///
1662 /// let (e, o) =
1663 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1664 /// assert_eq!(e.to_string(), "1.88");
1665 /// assert_eq!(o, Greater);
1666 ///
1667 /// let (e, o) =
1668 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1669 /// assert_eq!(e.to_string(), "1.8221188");
1670 /// assert_eq!(o, Less);
1671 ///
1672 /// let (e, o) =
1673 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1674 /// assert_eq!(e.to_string(), "1.8221207");
1675 /// assert_eq!(o, Greater);
1676 /// ```
1677 pub fn exp_rational_prec_round_ref(
1678 x: &Rational,
1679 prec: u64,
1680 rm: RoundingMode,
1681 ) -> (Self, Ordering) {
1682 assert_ne!(prec, 0);
1683 if *x == 0u32 {
1684 // exp(0) = 1, exactly.
1685 return (Self::one_prec(prec), Equal);
1686 }
1687 exp_rational_helper(x, prec, rm)
1688 }
1689
1690 #[allow(clippy::needless_pass_by_value)]
1691 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the nearest value
1692 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1693 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded exponential
1694 /// is less than, equal to, or greater than the exact exponential.
1695 ///
1696 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1697 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1698 /// description of the `Nearest` rounding mode.
1699 ///
1700 /// $$
1701 /// f(x,p) = e^x+\varepsilon,
1702 /// $$
1703 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$ (unless the result overflows or
1704 /// underflows; see below).
1705 ///
1706 /// The output has precision `prec`.
1707 ///
1708 /// Special cases:
1709 /// - $f(0,p)=1$.
1710 ///
1711 /// Overflow and underflow:
1712 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1713 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1714 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1715 ///
1716 /// If you want to use a rounding mode other than `Nearest`, consider using
1717 /// [`Float::exp_rational_prec_round`] instead.
1718 ///
1719 /// # Worst-case complexity
1720 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1721 ///
1722 /// $M(n, m) = O(n \log n + m \log m)$
1723 ///
1724 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1725 /// `x.significant_bits()`.
1726 ///
1727 /// # Panics
1728 /// Panics if `prec` is zero.
1729 ///
1730 /// # Examples
1731 /// ```
1732 /// use malachite_base::num::basic::traits::Zero;
1733 /// use malachite_float::Float;
1734 /// use malachite_q::Rational;
1735 /// use std::cmp::Ordering::*;
1736 ///
1737 /// let (e, o) = Float::exp_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1738 /// assert_eq!(e.to_string(), "1.81");
1739 /// assert_eq!(o, Less);
1740 ///
1741 /// let (e, o) = Float::exp_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1742 /// assert_eq!(e.to_string(), "1.8221188");
1743 /// assert_eq!(o, Less);
1744 ///
1745 /// let (e, o) = Float::exp_rational_prec(Rational::ZERO, 10);
1746 /// assert_eq!(e.to_string(), "1.0000");
1747 /// assert_eq!(o, Equal);
1748 /// ```
1749 #[inline]
1750 pub fn exp_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1751 Self::exp_rational_prec_round_ref(&x, prec, Nearest)
1752 }
1753
1754 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the nearest value
1755 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1756 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
1757 /// exponential is less than, equal to, or greater than the exact exponential.
1758 ///
1759 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1760 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1761 /// description of the `Nearest` rounding mode.
1762 ///
1763 /// $$
1764 /// f(x,p) = e^x+\varepsilon,
1765 /// $$
1766 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$ (unless the result overflows or
1767 /// underflows; see below).
1768 ///
1769 /// The output has precision `prec`.
1770 ///
1771 /// Special cases:
1772 /// - $f(0,p)=1$.
1773 ///
1774 /// Overflow and underflow:
1775 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1776 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1777 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1778 ///
1779 /// If you want to use a rounding mode other than `Nearest`, consider using
1780 /// [`Float::exp_rational_prec_round_ref`] instead.
1781 ///
1782 /// # Worst-case complexity
1783 /// $T(n, m) = O(n^{3/2} \log n \log\log n + m (\log m)^2 \log\log m)$
1784 ///
1785 /// $M(n, m) = O(n \log n + m \log m)$
1786 ///
1787 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1788 /// `x.significant_bits()`.
1789 ///
1790 /// # Panics
1791 /// Panics if `prec` is zero.
1792 ///
1793 /// # Examples
1794 /// ```
1795 /// use malachite_base::num::basic::traits::Zero;
1796 /// use malachite_float::Float;
1797 /// use malachite_q::Rational;
1798 /// use std::cmp::Ordering::*;
1799 ///
1800 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1801 /// assert_eq!(e.to_string(), "1.81");
1802 /// assert_eq!(o, Less);
1803 ///
1804 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1805 /// assert_eq!(e.to_string(), "1.8221188");
1806 /// assert_eq!(o, Less);
1807 ///
1808 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::ZERO, 10);
1809 /// assert_eq!(e.to_string(), "1.0000");
1810 /// assert_eq!(o, Equal);
1811 /// ```
1812 #[inline]
1813 pub fn exp_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1814 Self::exp_rational_prec_round_ref(x, prec, Nearest)
1815 }
1816}
1817
1818impl Exp for Float {
1819 type Output = Self;
1820
1821 /// Computes $e^x$, the exponential of a [`Float`], taking it by value.
1822 ///
1823 /// If the output has a precision, it is the precision of the input. If the exponential is
1824 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1825 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1826 /// rounding mode.
1827 ///
1828 /// $$
1829 /// f(x) = e^x+\varepsilon.
1830 /// $$
1831 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1832 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1833 /// where $p$ is the precision of the input.
1834 ///
1835 /// Special cases:
1836 /// - $f(\text{NaN})=\text{NaN}$
1837 /// - $f(\infty)=\infty$
1838 /// - $f(-\infty)=0.0$
1839 /// - $f(\pm0.0)=1.0$
1840 ///
1841 /// See the [`Float::exp_round`] documentation for information on overflow and underflow.
1842 ///
1843 /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::exp_round`]
1844 /// instead. If you want to specify the output precision, consider using [`Float::exp_prec`]. If
1845 /// you want both of these things, consider using [`Float::exp_prec_round`].
1846 ///
1847 /// # Worst-case complexity
1848 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1849 ///
1850 /// $M(n) = O(n \log n)$
1851 ///
1852 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1853 ///
1854 /// # Examples
1855 /// ```
1856 /// use malachite_base::num::arithmetic::traits::Exp;
1857 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1858 /// use malachite_float::Float;
1859 ///
1860 /// assert!(Float::NAN.exp().is_nan());
1861 /// assert_eq!(Float::INFINITY.exp(), Float::INFINITY);
1862 /// assert_eq!(Float::NEGATIVE_INFINITY.exp(), Float::ZERO);
1863 /// assert_eq!(
1864 /// Float::from_unsigned_prec(1u32, 100).0.exp().to_string(),
1865 /// "2.7182818284590452353602874713512"
1866 /// );
1867 /// ```
1868 #[inline]
1869 fn exp(self) -> Self {
1870 let prec = self.significant_bits();
1871 self.exp_prec_round(prec, Nearest).0
1872 }
1873}
1874
1875impl Exp for &Float {
1876 type Output = Float;
1877
1878 /// Computes $e^x$, the exponential of a [`Float`], taking it by reference.
1879 ///
1880 /// If the output has a precision, it is the precision of the input. If the exponential is
1881 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1882 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1883 /// rounding mode.
1884 ///
1885 /// $$
1886 /// f(x) = e^x+\varepsilon.
1887 /// $$
1888 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1889 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1890 /// where $p$ is the precision of the input.
1891 ///
1892 /// Special cases:
1893 /// - $f(\text{NaN})=\text{NaN}$
1894 /// - $f(\infty)=\infty$
1895 /// - $f(-\infty)=0.0$
1896 /// - $f(\pm0.0)=1.0$
1897 ///
1898 /// See the [`Float::exp_round`] documentation for information on overflow and underflow.
1899 ///
1900 /// If you want to use a rounding mode other than `Nearest`, consider using
1901 /// [`Float::exp_round_ref`] instead. If you want to specify the output precision, consider
1902 /// using [`Float::exp_prec_ref`]. If you want both of these things, consider using
1903 /// [`Float::exp_prec_round_ref`].
1904 ///
1905 /// # Worst-case complexity
1906 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1907 ///
1908 /// $M(n) = O(n \log n)$
1909 ///
1910 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1911 ///
1912 /// # Examples
1913 /// ```
1914 /// use malachite_base::num::arithmetic::traits::Exp;
1915 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1916 /// use malachite_float::Float;
1917 ///
1918 /// assert!((&Float::NAN).exp().is_nan());
1919 /// assert_eq!((&Float::INFINITY).exp(), Float::INFINITY);
1920 /// assert_eq!((&Float::NEGATIVE_INFINITY).exp(), Float::ZERO);
1921 /// assert_eq!(
1922 /// (&Float::from_unsigned_prec(1u32, 100).0).exp().to_string(),
1923 /// "2.7182818284590452353602874713512"
1924 /// );
1925 /// ```
1926 #[inline]
1927 fn exp(self) -> Float {
1928 let prec = self.significant_bits();
1929 self.exp_prec_round_ref(prec, Nearest).0
1930 }
1931}
1932
1933impl ExpAssign for Float {
1934 /// Computes $e^x$, the exponential of a [`Float`], in place.
1935 ///
1936 /// If the output has a precision, it is the precision of the input. If the exponential is
1937 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1938 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1939 /// rounding mode.
1940 ///
1941 /// $$
1942 /// x \gets e^x+\varepsilon.
1943 /// $$
1944 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1945 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1946 /// where $p$ is the precision of the input.
1947 ///
1948 /// See the [`Float::exp`] documentation for information on special cases, overflow, and
1949 /// underflow.
1950 ///
1951 /// If you want to use a rounding mode other than `Nearest`, consider using
1952 /// [`Float::exp_round_assign`] instead. If you want to specify the output precision, consider
1953 /// using [`Float::exp_prec_assign`]. If you want both of these things, consider using
1954 /// [`Float::exp_prec_round_assign`].
1955 ///
1956 /// # Worst-case complexity
1957 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1958 ///
1959 /// $M(n) = O(n \log n)$
1960 ///
1961 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1962 ///
1963 /// # Examples
1964 /// ```
1965 /// use malachite_base::num::arithmetic::traits::ExpAssign;
1966 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1967 /// use malachite_float::Float;
1968 ///
1969 /// let mut x = Float::NAN;
1970 /// x.exp_assign();
1971 /// assert!(x.is_nan());
1972 ///
1973 /// let mut x = Float::INFINITY;
1974 /// x.exp_assign();
1975 /// assert_eq!(x, Float::INFINITY);
1976 ///
1977 /// let mut x = Float::NEGATIVE_INFINITY;
1978 /// x.exp_assign();
1979 /// assert_eq!(x, Float::ZERO);
1980 ///
1981 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1982 /// x.exp_assign();
1983 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1984 /// ```
1985 #[inline]
1986 fn exp_assign(&mut self) {
1987 let prec = self.significant_bits();
1988 self.exp_prec_round_assign(prec, Nearest);
1989 }
1990}
1991
1992/// Computes $e^x$, the exponential of a primitive float. Using this function is more accurate than
1993/// using the default `exp` function or the one provided by `libm`.
1994///
1995/// $$
1996/// f(x) = e^x+\varepsilon.
1997/// $$
1998/// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1999/// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$, where
2000/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
2001/// [`f64`], but less if the output is subnormal).
2002///
2003/// Special cases:
2004/// - $f(\text{NaN})=\text{NaN}$
2005/// - $f(\infty)=\infty$
2006/// - $f(-\infty)=0.0$
2007/// - $f(\pm0.0)=1.0$
2008///
2009/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
2010/// `x` gives `0.0`.
2011///
2012/// # Worst-case complexity
2013/// Constant time and additional memory.
2014///
2015/// # Examples
2016/// ```
2017/// use malachite_base::num::basic::traits::NegativeInfinity;
2018/// use malachite_base::num::float::NiceFloat;
2019/// use malachite_float::float::arithmetic::exp::primitive_float_exp;
2020///
2021/// assert!(primitive_float_exp(f32::NAN).is_nan());
2022/// assert_eq!(
2023/// NiceFloat(primitive_float_exp(f32::INFINITY)),
2024/// NiceFloat(f32::INFINITY)
2025/// );
2026/// assert_eq!(
2027/// NiceFloat(primitive_float_exp(f32::NEGATIVE_INFINITY)),
2028/// NiceFloat(0.0)
2029/// );
2030/// assert_eq!(NiceFloat(primitive_float_exp(0.0f32)), NiceFloat(1.0));
2031/// assert_eq!(NiceFloat(primitive_float_exp(1.0f32)), NiceFloat(2.7182817));
2032/// ```
2033#[inline]
2034#[allow(clippy::type_repetition_in_bounds)]
2035pub fn primitive_float_exp<T: PrimitiveFloat>(x: T) -> T
2036where
2037 Float: From<T> + PartialOrd<T>,
2038 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2039{
2040 emulate_float_to_float_fn(Float::exp_prec, x)
2041}
2042
2043/// Computes $e^x$, the exponential of a [`Rational`], returning the result as a primitive float.
2044///
2045/// $$
2046/// f(x) = e^x+\varepsilon.
2047/// $$
2048/// - If $e^x$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
2049/// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$, where
2050/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
2051/// [`f64`], but less if the output is subnormal).
2052///
2053/// Special cases:
2054/// - $f(0)=1$
2055///
2056/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
2057/// `x` gives `0.0`.
2058///
2059/// # Worst-case complexity
2060/// $T(m) = O(m (\log m)^2 \log\log m)$
2061///
2062/// $M(m) = O(m \log m)$
2063///
2064/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2065///
2066/// # Examples
2067/// ```
2068/// use malachite_base::num::basic::traits::Zero;
2069/// use malachite_base::num::float::NiceFloat;
2070/// use malachite_float::float::arithmetic::exp::primitive_float_exp_rational;
2071/// use malachite_q::Rational;
2072///
2073/// assert_eq!(
2074/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::ZERO)),
2075/// NiceFloat(1.0)
2076/// );
2077/// assert_eq!(
2078/// NiceFloat(primitive_float_exp_rational::<f64>(
2079/// &Rational::from_unsigneds(1u8, 3)
2080/// )),
2081/// NiceFloat(1.3956124250860895)
2082/// );
2083/// assert_eq!(
2084/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::from(10000))),
2085/// NiceFloat(f64::INFINITY)
2086/// );
2087/// assert_eq!(
2088/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::from(-10000))),
2089/// NiceFloat(0.0)
2090/// );
2091/// ```
2092#[inline]
2093#[allow(clippy::type_repetition_in_bounds)]
2094pub fn primitive_float_exp_rational<T: PrimitiveFloat>(x: &Rational) -> T
2095where
2096 Float: PartialOrd<T>,
2097 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2098{
2099 emulate_rational_to_float_fn(Float::exp_rational_prec_ref, x)
2100}