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