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::WIDTH_MINUS_1;
25use crate::{Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, floor_and_ceiling};
26use alloc::vec;
27use core::cmp::Ordering::{self, Equal, Greater, Less};
28use core::cmp::max;
29use core::mem::swap;
30use malachite_base::fail_on_untested_path;
31use malachite_base::num::arithmetic::traits::{
32 CeilingLogBase2, Exp, ExpAssign, FloorRoot, FloorSqrt, IsPowerOf2, NegAssign, Parity, PowerOf2,
33 ShrRoundAssign, Sign, Square, SquareAssign, WrappingAddAssign,
34};
35use malachite_base::num::basic::floats::PrimitiveFloat;
36use malachite_base::num::basic::integers::PrimitiveInt;
37use malachite_base::num::basic::traits::{
38 Infinity as InfinityTrait, NaN as NaNTrait, One, Zero as ZeroTrait,
39};
40use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom, WrappingFrom};
41use malachite_base::num::logic::traits::SignificantBits;
42use malachite_base::rounding_modes::RoundingMode::{
43 self, Ceiling, Down, Exact, Floor, Nearest, Up,
44};
45use malachite_nz::integer::Integer;
46use malachite_nz::natural::Natural;
47use malachite_nz::natural::arithmetic::float_extras::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.
83fn 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 == 0 {
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 == 0 {
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 == 0 {
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 != 0 {
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 <<= 1;
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(2, rm);
498 if inex2 != Equal {
499 // Underflow while unscaling.
500 if rm == Nearest
501 && inexact == Less
502 && matches!(y.0, Zero { .. })
503 && ey == i64::from(Float::MIN_EXPONENT) + 1
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) = O(n^{3/2} \log n \log\log n)$
911 ///
912 /// $M(n) = O(n \log n)$
913 ///
914 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
915 ///
916 /// # Panics
917 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
918 /// precision.
919 ///
920 /// # Examples
921 /// ```
922 /// use malachite_base::rounding_modes::RoundingMode::*;
923 /// use malachite_float::Float;
924 /// use std::cmp::Ordering::*;
925 ///
926 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
927 /// .0
928 /// .exp_prec_round(5, Floor);
929 /// assert_eq!(e.to_string(), "2.62");
930 /// assert_eq!(o, Less);
931 ///
932 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
933 /// .0
934 /// .exp_prec_round(5, Ceiling);
935 /// assert_eq!(e.to_string(), "2.75");
936 /// assert_eq!(o, Greater);
937 ///
938 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
939 /// .0
940 /// .exp_prec_round(5, Nearest);
941 /// assert_eq!(e.to_string(), "2.75");
942 /// assert_eq!(o, Greater);
943 ///
944 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
945 /// .0
946 /// .exp_prec_round(20, Floor);
947 /// assert_eq!(e.to_string(), "2.7182808");
948 /// assert_eq!(o, Less);
949 ///
950 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
951 /// .0
952 /// .exp_prec_round(20, Ceiling);
953 /// assert_eq!(e.to_string(), "2.7182846");
954 /// assert_eq!(o, Greater);
955 ///
956 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
957 /// .0
958 /// .exp_prec_round(20, Nearest);
959 /// assert_eq!(e.to_string(), "2.7182808");
960 /// assert_eq!(o, Less);
961 /// ```
962 #[inline]
963 pub fn exp_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
964 self.exp_prec_round_ref(prec, rm)
965 }
966
967 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the specified
968 /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
969 /// [`Ordering`] is also returned, indicating whether the rounded exponential is less than,
970 /// equal to, or greater than the exact exponential. Although `NaN`s are not comparable to any
971 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
972 ///
973 /// See [`RoundingMode`] for a description of the possible rounding modes.
974 ///
975 /// $$
976 /// f(x,p,m) = e^x+\varepsilon.
977 /// $$
978 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
979 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
980 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
981 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
982 /// 2^{\lfloor\log_2 e^x\rfloor-p}$.
983 ///
984 /// If the output has a precision, it is `prec`.
985 ///
986 /// Special cases:
987 /// - $f(\text{NaN},p,m)=\text{NaN}$
988 /// - $f(\infty,p,m)=\infty$
989 /// - $f(-\infty,p,m)=0.0$
990 /// - $f(\pm0.0,p,m)=1.0$
991 ///
992 /// Overflow and underflow:
993 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
994 /// returned instead.
995 /// - 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
996 /// returned instead.
997 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
998 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
999 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1000 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1001 /// instead.
1002 ///
1003 /// If you know you'll be using `Nearest`, consider using [`Float::exp_prec_ref`] instead. If
1004 /// you know that your target precision is the precision of the input, consider using
1005 /// [`Float::exp_round_ref`] instead. If both of these things are true, consider using
1006 /// `(&Float).exp()` instead.
1007 ///
1008 /// # Worst-case complexity
1009 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1010 ///
1011 /// $M(n) = O(n \log n)$
1012 ///
1013 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1014 ///
1015 /// # Panics
1016 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1017 /// precision.
1018 ///
1019 /// # Examples
1020 /// ```
1021 /// use malachite_base::rounding_modes::RoundingMode::*;
1022 /// use malachite_float::Float;
1023 /// use std::cmp::Ordering::*;
1024 ///
1025 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1026 /// .0
1027 /// .exp_prec_round_ref(5, Floor);
1028 /// assert_eq!(e.to_string(), "2.62");
1029 /// assert_eq!(o, Less);
1030 ///
1031 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1032 /// .0
1033 /// .exp_prec_round_ref(5, Ceiling);
1034 /// assert_eq!(e.to_string(), "2.75");
1035 /// assert_eq!(o, Greater);
1036 ///
1037 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1038 /// .0
1039 /// .exp_prec_round_ref(5, Nearest);
1040 /// assert_eq!(e.to_string(), "2.75");
1041 /// assert_eq!(o, Greater);
1042 ///
1043 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1044 /// .0
1045 /// .exp_prec_round_ref(20, Floor);
1046 /// assert_eq!(e.to_string(), "2.7182808");
1047 /// assert_eq!(o, Less);
1048 ///
1049 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1050 /// .0
1051 /// .exp_prec_round_ref(20, Ceiling);
1052 /// assert_eq!(e.to_string(), "2.7182846");
1053 /// assert_eq!(o, Greater);
1054 ///
1055 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1056 /// .0
1057 /// .exp_prec_round_ref(20, Nearest);
1058 /// assert_eq!(e.to_string(), "2.7182808");
1059 /// assert_eq!(o, Less);
1060 /// ```
1061 pub fn exp_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1062 assert_ne!(prec, 0);
1063 match &self.0 {
1064 NaN => (Self::NAN, Equal),
1065 // exp(+inf) = +inf; exp(-inf) = +0
1066 Infinity { sign } => {
1067 if *sign {
1068 (Self::INFINITY, Equal)
1069 } else {
1070 (Self::ZERO, Equal)
1071 }
1072 }
1073 // exp(+0) = exp(-0) = 1
1074 Zero { .. } => (Self::one_prec(prec), Equal),
1075 Finite { .. } => exp_prec_round_normal_ref(self, prec, rm),
1076 }
1077 }
1078
1079 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the nearest value of
1080 /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
1081 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1082 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1083 /// returns a `NaN` it also returns `Equal`.
1084 ///
1085 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1086 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1087 /// description of the `Nearest` rounding mode.
1088 ///
1089 /// $$
1090 /// f(x,p) = e^x+\varepsilon.
1091 /// $$
1092 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1093 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1094 ///
1095 /// If the output has a precision, it is `prec`.
1096 ///
1097 /// Special cases:
1098 /// - $f(\text{NaN},p)=\text{NaN}$
1099 /// - $f(\infty,p)=\infty$
1100 /// - $f(-\infty,p)=0.0$
1101 /// - $f(\pm0.0,p)=1.0$
1102 ///
1103 /// Overflow and underflow:
1104 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1105 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1106 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1107 ///
1108 /// If you want to use a rounding mode other than `Nearest`, consider using
1109 /// [`Float::exp_prec_round`] instead. If you know that your target precision is the precision
1110 /// of the input, consider using [`Float::exp`] instead.
1111 ///
1112 /// # Worst-case complexity
1113 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1114 ///
1115 /// $M(n) = O(n \log n)$
1116 ///
1117 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1118 ///
1119 /// # Examples
1120 /// ```
1121 /// use malachite_float::Float;
1122 /// use std::cmp::Ordering::*;
1123 ///
1124 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec(5);
1125 /// assert_eq!(e.to_string(), "2.75");
1126 /// assert_eq!(o, Greater);
1127 ///
1128 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec(20);
1129 /// assert_eq!(e.to_string(), "2.7182808");
1130 /// assert_eq!(o, Less);
1131 /// ```
1132 #[inline]
1133 pub fn exp_prec(self, prec: u64) -> (Self, Ordering) {
1134 self.exp_prec_round(prec, Nearest)
1135 }
1136
1137 /// Computes $e^x$, the exponential of a [`Float`], rounding the result to the nearest value of
1138 /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
1139 /// returned, indicating whether the rounded exponential is less than, equal to, or greater than
1140 /// the exact exponential. Although `NaN`s are not comparable to any [`Float`], whenever this
1141 /// function returns a `NaN` it also returns `Equal`.
1142 ///
1143 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1144 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1145 /// description of the `Nearest` rounding mode.
1146 ///
1147 /// $$
1148 /// f(x,p) = e^x+\varepsilon.
1149 /// $$
1150 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1151 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1152 ///
1153 /// If the output has a precision, it is `prec`.
1154 ///
1155 /// Special cases:
1156 /// - $f(\text{NaN},p)=\text{NaN}$
1157 /// - $f(\infty,p)=\infty$
1158 /// - $f(-\infty,p)=0.0$
1159 /// - $f(\pm0.0,p)=1.0$
1160 ///
1161 /// Overflow and underflow:
1162 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1163 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1164 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1165 ///
1166 /// If you want to use a rounding mode other than `Nearest`, consider using
1167 /// [`Float::exp_prec_round_ref`] instead. If you know that your target precision is the
1168 /// precision of the input, consider using `(&Float).exp()` instead.
1169 ///
1170 /// # Worst-case complexity
1171 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1172 ///
1173 /// $M(n) = O(n \log n)$
1174 ///
1175 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1176 ///
1177 /// # Examples
1178 /// ```
1179 /// use malachite_float::Float;
1180 /// use std::cmp::Ordering::*;
1181 ///
1182 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec_ref(5);
1183 /// assert_eq!(e.to_string(), "2.75");
1184 /// assert_eq!(o, Greater);
1185 ///
1186 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_prec_ref(20);
1187 /// assert_eq!(e.to_string(), "2.7182808");
1188 /// assert_eq!(o, Less);
1189 /// ```
1190 #[inline]
1191 pub fn exp_prec_ref(&self, prec: u64) -> (Self, Ordering) {
1192 self.exp_prec_round_ref(prec, Nearest)
1193 }
1194
1195 /// Computes $e^x$, the exponential of a [`Float`], rounding the result with the specified
1196 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
1197 /// whether the rounded exponential is less than, equal to, or greater than the exact
1198 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1199 /// returns a `NaN` it also returns `Equal`.
1200 ///
1201 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1202 /// description of the possible rounding modes.
1203 ///
1204 /// $$
1205 /// f(x,m) = e^x+\varepsilon.
1206 /// $$
1207 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1208 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1209 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1210 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1211 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1212 ///
1213 /// If the output has a precision, it is the precision of the input.
1214 ///
1215 /// Special cases:
1216 /// - $f(\text{NaN},m)=\text{NaN}$
1217 /// - $f(\infty,m)=\infty$
1218 /// - $f(-\infty,m)=0.0$
1219 /// - $f(\pm0.0,m)=1.0$
1220 ///
1221 /// See the [`Float::exp_prec_round`] documentation for information on overflow and underflow.
1222 ///
1223 /// If you want to specify an output precision, consider using [`Float::exp_prec_round`]
1224 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1225 /// [`Float::exp`] instead.
1226 ///
1227 /// # Worst-case complexity
1228 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1229 ///
1230 /// $M(n) = O(n \log n)$
1231 ///
1232 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1233 ///
1234 /// # Panics
1235 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1236 /// precision.
1237 ///
1238 /// # Examples
1239 /// ```
1240 /// use malachite_base::rounding_modes::RoundingMode::*;
1241 /// use malachite_float::Float;
1242 /// use std::cmp::Ordering::*;
1243 ///
1244 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Floor);
1245 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1246 /// assert_eq!(o, Less);
1247 ///
1248 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Ceiling);
1249 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713544");
1250 /// assert_eq!(o, Greater);
1251 ///
1252 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round(Nearest);
1253 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1254 /// assert_eq!(o, Less);
1255 /// ```
1256 #[inline]
1257 pub fn exp_round(self, rm: RoundingMode) -> (Self, Ordering) {
1258 let prec = self.significant_bits();
1259 self.exp_prec_round(prec, rm)
1260 }
1261
1262 /// Computes $e^x$, the exponential of a [`Float`], rounding the result with the specified
1263 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
1264 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1265 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1266 /// returns a `NaN` it also returns `Equal`.
1267 ///
1268 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1269 /// description of the possible rounding modes.
1270 ///
1271 /// $$
1272 /// f(x,m) = e^x+\varepsilon.
1273 /// $$
1274 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1275 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1276 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1277 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1278 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1279 ///
1280 /// If the output has a precision, it is the precision of the input.
1281 ///
1282 /// Special cases:
1283 /// - $f(\text{NaN},m)=\text{NaN}$
1284 /// - $f(\infty,m)=\infty$
1285 /// - $f(-\infty,m)=0.0$
1286 /// - $f(\pm0.0,m)=1.0$
1287 ///
1288 /// See the [`Float::exp_prec_round`] documentation for information on overflow and underflow.
1289 ///
1290 /// If you want to specify an output precision, consider using [`Float::exp_prec_round_ref`]
1291 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1292 /// `(&Float).exp()` instead.
1293 ///
1294 /// # Worst-case complexity
1295 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1296 ///
1297 /// $M(n) = O(n \log n)$
1298 ///
1299 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1300 ///
1301 /// # Panics
1302 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1303 /// precision.
1304 ///
1305 /// # Examples
1306 /// ```
1307 /// use malachite_base::rounding_modes::RoundingMode::*;
1308 /// use malachite_float::Float;
1309 /// use std::cmp::Ordering::*;
1310 ///
1311 /// let (e, o) = Float::from_unsigned_prec(1u32, 100).0.exp_round_ref(Floor);
1312 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1313 /// assert_eq!(o, Less);
1314 ///
1315 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1316 /// .0
1317 /// .exp_round_ref(Ceiling);
1318 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713544");
1319 /// assert_eq!(o, Greater);
1320 ///
1321 /// let (e, o) = Float::from_unsigned_prec(1u32, 100)
1322 /// .0
1323 /// .exp_round_ref(Nearest);
1324 /// assert_eq!(e.to_string(), "2.7182818284590452353602874713512");
1325 /// assert_eq!(o, Less);
1326 /// ```
1327 #[inline]
1328 pub fn exp_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1329 let prec = self.significant_bits();
1330 self.exp_prec_round_ref(prec, rm)
1331 }
1332
1333 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result to the
1334 /// specified precision and with the specified rounding mode. An [`Ordering`] is returned,
1335 /// indicating whether the rounded exponential is less than, equal to, or greater than the exact
1336 /// exponential. Although `NaN`s are not comparable to any [`Float`], whenever this function
1337 /// sets the [`Float`] to `NaN` it also returns `Equal`.
1338 ///
1339 /// See [`RoundingMode`] for a description of the possible rounding modes.
1340 ///
1341 /// $$
1342 /// x \gets e^x+\varepsilon.
1343 /// $$
1344 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1345 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1346 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1347 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1348 /// 2^{\lfloor\log_2 e^x\rfloor-p}$.
1349 ///
1350 /// If the output has a precision, it is `prec`.
1351 ///
1352 /// See the [`Float::exp_prec_round`] documentation for information on special cases, overflow,
1353 /// and underflow.
1354 ///
1355 /// If you know you'll be using `Nearest`, consider using [`Float::exp_prec_assign`] instead. If
1356 /// you know that your target precision is the precision of the input, consider using
1357 /// [`Float::exp_round_assign`] instead. If both of these things are true, consider using
1358 /// [`Float::exp_assign`] instead.
1359 ///
1360 /// # Worst-case complexity
1361 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1362 ///
1363 /// $M(n) = O(n \log n)$
1364 ///
1365 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1366 ///
1367 /// # Panics
1368 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1369 /// precision.
1370 ///
1371 /// # Examples
1372 /// ```
1373 /// use malachite_base::rounding_modes::RoundingMode::*;
1374 /// use malachite_float::Float;
1375 /// use std::cmp::Ordering::*;
1376 ///
1377 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1378 /// assert_eq!(x.exp_prec_round_assign(5, Floor), Less);
1379 /// assert_eq!(x.to_string(), "2.62");
1380 ///
1381 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1382 /// assert_eq!(x.exp_prec_round_assign(5, Ceiling), Greater);
1383 /// assert_eq!(x.to_string(), "2.75");
1384 ///
1385 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1386 /// assert_eq!(x.exp_prec_round_assign(5, Nearest), Greater);
1387 /// assert_eq!(x.to_string(), "2.75");
1388 ///
1389 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1390 /// assert_eq!(x.exp_prec_round_assign(20, Floor), Less);
1391 /// assert_eq!(x.to_string(), "2.7182808");
1392 ///
1393 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1394 /// assert_eq!(x.exp_prec_round_assign(20, Ceiling), Greater);
1395 /// assert_eq!(x.to_string(), "2.7182846");
1396 ///
1397 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1398 /// assert_eq!(x.exp_prec_round_assign(20, Nearest), Less);
1399 /// assert_eq!(x.to_string(), "2.7182808");
1400 /// ```
1401 #[inline]
1402 pub fn exp_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1403 let mut x = Self::ZERO;
1404 swap(self, &mut x);
1405 let o;
1406 (*self, o) = x.exp_prec_round(prec, rm);
1407 o
1408 }
1409
1410 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result to the nearest
1411 /// value of the specified precision. An [`Ordering`] is returned, indicating whether the
1412 /// rounded exponential is less than, equal to, or greater than the exact exponential. Although
1413 /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
1414 /// `NaN` it also returns `Equal`.
1415 ///
1416 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1417 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1418 /// description of the `Nearest` rounding mode.
1419 ///
1420 /// $$
1421 /// x \gets e^x+\varepsilon.
1422 /// $$
1423 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1424 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$.
1425 ///
1426 /// If the output has a precision, it is `prec`.
1427 ///
1428 /// See the [`Float::exp_prec`] documentation for information on special cases, overflow, and
1429 /// underflow.
1430 ///
1431 /// If you want to use a rounding mode other than `Nearest`, consider using
1432 /// [`Float::exp_prec_round_assign`] instead. If you know that your target precision is the
1433 /// precision of the input, consider using [`Float::exp_assign`] instead.
1434 ///
1435 /// # Worst-case complexity
1436 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1437 ///
1438 /// $M(n) = O(n \log n)$
1439 ///
1440 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1441 ///
1442 /// # Examples
1443 /// ```
1444 /// use malachite_float::Float;
1445 /// use std::cmp::Ordering::*;
1446 ///
1447 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1448 /// assert_eq!(x.exp_prec_assign(5), Greater);
1449 /// assert_eq!(x.to_string(), "2.75");
1450 ///
1451 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1452 /// assert_eq!(x.exp_prec_assign(20), Less);
1453 /// assert_eq!(x.to_string(), "2.7182808");
1454 /// ```
1455 #[inline]
1456 pub fn exp_prec_assign(&mut self, prec: u64) -> Ordering {
1457 self.exp_prec_round_assign(prec, Nearest)
1458 }
1459
1460 /// Computes $e^x$, the exponential of a [`Float`], in place, rounding the result with the
1461 /// specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded
1462 /// exponential is less than, equal to, or greater than the exact exponential. Although `NaN`s
1463 /// are not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it
1464 /// also returns `Equal`.
1465 ///
1466 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1467 /// description of the possible rounding modes.
1468 ///
1469 /// $$
1470 /// x \gets e^x+\varepsilon.
1471 /// $$
1472 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1473 /// - If $e^x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1474 /// 2^{\lfloor\log_2 e^x\rfloor-p+1}$, where $p$ is the precision of the input.
1475 /// - If $e^x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1476 /// 2^{\lfloor\log_2 e^x\rfloor-p}$, where $p$ is the precision of the input.
1477 ///
1478 /// If the output has a precision, it is the precision of the input.
1479 ///
1480 /// See the [`Float::exp_round`] documentation for information on special cases, overflow, and
1481 /// underflow.
1482 ///
1483 /// If you want to specify an output precision, consider using [`Float::exp_prec_round_assign`]
1484 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1485 /// [`Float::exp_assign`] instead.
1486 ///
1487 /// # Worst-case complexity
1488 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1489 ///
1490 /// $M(n) = O(n \log n)$
1491 ///
1492 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1493 ///
1494 /// # Panics
1495 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
1496 /// precision.
1497 ///
1498 /// # Examples
1499 /// ```
1500 /// use malachite_base::rounding_modes::RoundingMode::*;
1501 /// use malachite_float::Float;
1502 /// use std::cmp::Ordering::*;
1503 ///
1504 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1505 /// assert_eq!(x.exp_round_assign(Floor), Less);
1506 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1507 ///
1508 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1509 /// assert_eq!(x.exp_round_assign(Ceiling), Greater);
1510 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713544");
1511 ///
1512 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1513 /// assert_eq!(x.exp_round_assign(Nearest), Less);
1514 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1515 /// ```
1516 #[inline]
1517 pub fn exp_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1518 let prec = self.significant_bits();
1519 self.exp_prec_round_assign(prec, rm)
1520 }
1521
1522 #[allow(clippy::needless_pass_by_value)]
1523 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the specified
1524 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1525 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1526 /// rounded exponential is less than, equal to, or greater than the exact exponential.
1527 ///
1528 /// See [`RoundingMode`] for a description of the possible rounding modes.
1529 ///
1530 /// $$
1531 /// f(x,p,m) = e^x+\varepsilon.
1532 /// $$
1533 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1534 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$.
1535 ///
1536 /// These bounds do not apply when the result overflows or underflows; see below.
1537 ///
1538 /// The output has precision `prec`.
1539 ///
1540 /// Special cases:
1541 /// - $f(0,p,m)=1$.
1542 ///
1543 /// Overflow and underflow:
1544 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1545 /// returned instead.
1546 /// - 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
1547 /// returned instead.
1548 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1549 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1550 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1551 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1552 /// instead.
1553 ///
1554 /// If you know you'll be using `Nearest`, consider using [`Float::exp_rational_prec`] instead.
1555 ///
1556 /// # Worst-case complexity
1557 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1558 ///
1559 /// $M(n) = O(n \log n)$
1560 ///
1561 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1562 ///
1563 /// # Panics
1564 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1565 /// with the given precision (which is the case for every nonzero input).
1566 ///
1567 /// # Examples
1568 /// ```
1569 /// use malachite_base::rounding_modes::RoundingMode::*;
1570 /// use malachite_float::Float;
1571 /// use malachite_q::Rational;
1572 /// use std::cmp::Ordering::*;
1573 ///
1574 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1575 /// assert_eq!(e.to_string(), "1.81");
1576 /// assert_eq!(o, Less);
1577 ///
1578 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1579 /// assert_eq!(e.to_string(), "1.88");
1580 /// assert_eq!(o, Greater);
1581 ///
1582 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1583 /// assert_eq!(e.to_string(), "1.8221188");
1584 /// assert_eq!(o, Less);
1585 ///
1586 /// let (e, o) = Float::exp_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1587 /// assert_eq!(e.to_string(), "1.8221207");
1588 /// assert_eq!(o, Greater);
1589 /// ```
1590 #[inline]
1591 pub fn exp_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1592 Self::exp_rational_prec_round_ref(&x, prec, rm)
1593 }
1594
1595 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the specified
1596 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1597 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1598 /// rounded exponential is less than, equal to, or greater than the exact exponential.
1599 ///
1600 /// See [`RoundingMode`] for a description of the possible rounding modes.
1601 ///
1602 /// $$
1603 /// f(x,p,m) = e^x+\varepsilon.
1604 /// $$
1605 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p+1}$.
1606 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$.
1607 ///
1608 /// These bounds do not apply when the result overflows or underflows; see below.
1609 ///
1610 /// The output has precision `prec`.
1611 ///
1612 /// Special cases:
1613 /// - $f(0,p,m)=1$.
1614 ///
1615 /// Overflow and underflow:
1616 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1617 /// returned instead.
1618 /// - 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
1619 /// returned instead.
1620 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1621 /// - If $f(x,p,m)<2^{-2^{30}}$ and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned instead.
1622 /// - If $f(x,p,m)\leq2^{-2^{30}-1}$ and $m$ is `Nearest`, $0.0$ is returned instead.
1623 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$ and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1624 /// instead.
1625 ///
1626 /// If you know you'll be using `Nearest`, consider using [`Float::exp_rational_prec_ref`]
1627 /// instead.
1628 ///
1629 /// # Worst-case complexity
1630 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1631 ///
1632 /// $M(n) = O(n \log n)$
1633 ///
1634 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1635 ///
1636 /// # Panics
1637 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1638 /// with the given precision (which is the case for every nonzero input).
1639 ///
1640 /// # Examples
1641 /// ```
1642 /// use malachite_base::rounding_modes::RoundingMode::*;
1643 /// use malachite_float::Float;
1644 /// use malachite_q::Rational;
1645 /// use std::cmp::Ordering::*;
1646 ///
1647 /// let (e, o) =
1648 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1649 /// assert_eq!(e.to_string(), "1.81");
1650 /// assert_eq!(o, Less);
1651 ///
1652 /// let (e, o) =
1653 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1654 /// assert_eq!(e.to_string(), "1.88");
1655 /// assert_eq!(o, Greater);
1656 ///
1657 /// let (e, o) =
1658 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1659 /// assert_eq!(e.to_string(), "1.8221188");
1660 /// assert_eq!(o, Less);
1661 ///
1662 /// let (e, o) =
1663 /// Float::exp_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1664 /// assert_eq!(e.to_string(), "1.8221207");
1665 /// assert_eq!(o, Greater);
1666 /// ```
1667 pub fn exp_rational_prec_round_ref(
1668 x: &Rational,
1669 prec: u64,
1670 rm: RoundingMode,
1671 ) -> (Self, Ordering) {
1672 assert_ne!(prec, 0);
1673 if *x == 0u32 {
1674 // exp(0) = 1, exactly.
1675 return (Self::one_prec(prec), Equal);
1676 }
1677 exp_rational_helper(x, prec, rm)
1678 }
1679
1680 #[allow(clippy::needless_pass_by_value)]
1681 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the nearest value
1682 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1683 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded exponential
1684 /// is less than, equal to, or greater than the exact exponential.
1685 ///
1686 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1687 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1688 /// description of the `Nearest` rounding mode.
1689 ///
1690 /// $$
1691 /// f(x,p) = e^x+\varepsilon,
1692 /// $$
1693 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$ (unless the result overflows or
1694 /// underflows; see below).
1695 ///
1696 /// The output has precision `prec`.
1697 ///
1698 /// Special cases:
1699 /// - $f(0,p)=1$.
1700 ///
1701 /// Overflow and underflow:
1702 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1703 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1704 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1705 ///
1706 /// If you want to use a rounding mode other than `Nearest`, consider using
1707 /// [`Float::exp_rational_prec_round`] instead.
1708 ///
1709 /// # Worst-case complexity
1710 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1711 ///
1712 /// $M(n) = O(n \log n)$
1713 ///
1714 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1715 ///
1716 /// # Panics
1717 /// Panics if `prec` is zero.
1718 ///
1719 /// # Examples
1720 /// ```
1721 /// use malachite_float::Float;
1722 /// use malachite_q::Rational;
1723 /// use std::cmp::Ordering::*;
1724 ///
1725 /// let (e, o) = Float::exp_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1726 /// assert_eq!(e.to_string(), "1.81");
1727 /// assert_eq!(o, Less);
1728 ///
1729 /// let (e, o) = Float::exp_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1730 /// assert_eq!(e.to_string(), "1.8221188");
1731 /// assert_eq!(o, Less);
1732 ///
1733 /// let (e, o) = Float::exp_rational_prec(Rational::from(0), 10);
1734 /// assert_eq!(e.to_string(), "1.0000");
1735 /// assert_eq!(o, Equal);
1736 /// ```
1737 #[inline]
1738 pub fn exp_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1739 Self::exp_rational_prec_round_ref(&x, prec, Nearest)
1740 }
1741
1742 /// Computes $e^x$, the exponential of a [`Rational`], rounding the result to the nearest value
1743 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1744 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
1745 /// exponential is less than, equal to, or greater than the exact exponential.
1746 ///
1747 /// If the exponential is equidistant from two [`Float`]s with the specified precision, the
1748 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1749 /// description of the `Nearest` rounding mode.
1750 ///
1751 /// $$
1752 /// f(x,p) = e^x+\varepsilon,
1753 /// $$
1754 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 e^x\rfloor-p}$ (unless the result overflows or
1755 /// underflows; see below).
1756 ///
1757 /// The output has precision `prec`.
1758 ///
1759 /// Special cases:
1760 /// - $f(0,p)=1$.
1761 ///
1762 /// Overflow and underflow:
1763 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1764 /// - If $f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1765 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1766 ///
1767 /// If you want to use a rounding mode other than `Nearest`, consider using
1768 /// [`Float::exp_rational_prec_round_ref`] instead.
1769 ///
1770 /// # Worst-case complexity
1771 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1772 ///
1773 /// $M(n) = O(n \log n)$
1774 ///
1775 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1776 ///
1777 /// # Panics
1778 /// Panics if `prec` is zero.
1779 ///
1780 /// # Examples
1781 /// ```
1782 /// use malachite_float::Float;
1783 /// use malachite_q::Rational;
1784 /// use std::cmp::Ordering::*;
1785 ///
1786 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1787 /// assert_eq!(e.to_string(), "1.81");
1788 /// assert_eq!(o, Less);
1789 ///
1790 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1791 /// assert_eq!(e.to_string(), "1.8221188");
1792 /// assert_eq!(o, Less);
1793 ///
1794 /// let (e, o) = Float::exp_rational_prec_ref(&Rational::from(0), 10);
1795 /// assert_eq!(e.to_string(), "1.0000");
1796 /// assert_eq!(o, Equal);
1797 /// ```
1798 #[inline]
1799 pub fn exp_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1800 Self::exp_rational_prec_round_ref(x, prec, Nearest)
1801 }
1802}
1803
1804impl Exp for Float {
1805 type Output = Self;
1806
1807 /// Computes $e^x$, the exponential of a [`Float`], taking it by value.
1808 ///
1809 /// If the output has a precision, it is the precision of the input. If the exponential is
1810 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1811 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1812 /// rounding mode.
1813 ///
1814 /// $$
1815 /// f(x) = e^x+\varepsilon.
1816 /// $$
1817 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1818 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1819 /// where $p$ is the precision of the input.
1820 ///
1821 /// Special cases:
1822 /// - $f(\text{NaN})=\text{NaN}$
1823 /// - $f(\infty)=\infty$
1824 /// - $f(-\infty)=0.0$
1825 /// - $f(\pm0.0)=1.0$
1826 ///
1827 /// See the [`Float::exp_round`] documentation for information on overflow and underflow.
1828 ///
1829 /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::exp_round`]
1830 /// instead. If you want to specify the output precision, consider using [`Float::exp_prec`]. If
1831 /// you want both of these things, consider using [`Float::exp_prec_round`].
1832 ///
1833 /// # Worst-case complexity
1834 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1835 ///
1836 /// $M(n) = O(n \log n)$
1837 ///
1838 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1839 ///
1840 /// # Examples
1841 /// ```
1842 /// use malachite_base::num::arithmetic::traits::Exp;
1843 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1844 /// use malachite_float::Float;
1845 ///
1846 /// assert!(Float::NAN.exp().is_nan());
1847 /// assert_eq!(Float::INFINITY.exp(), Float::INFINITY);
1848 /// assert_eq!(Float::NEGATIVE_INFINITY.exp(), Float::ZERO);
1849 /// assert_eq!(
1850 /// Float::from_unsigned_prec(1u32, 100).0.exp().to_string(),
1851 /// "2.7182818284590452353602874713512"
1852 /// );
1853 /// ```
1854 #[inline]
1855 fn exp(self) -> Self {
1856 let prec = self.significant_bits();
1857 self.exp_prec_round(prec, Nearest).0
1858 }
1859}
1860
1861impl Exp for &Float {
1862 type Output = Float;
1863
1864 /// Computes $e^x$, the exponential of a [`Float`], taking it by reference.
1865 ///
1866 /// If the output has a precision, it is the precision of the input. If the exponential is
1867 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1868 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1869 /// rounding mode.
1870 ///
1871 /// $$
1872 /// f(x) = e^x+\varepsilon.
1873 /// $$
1874 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1875 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1876 /// where $p$ is the precision of the input.
1877 ///
1878 /// Special cases:
1879 /// - $f(\text{NaN})=\text{NaN}$
1880 /// - $f(\infty)=\infty$
1881 /// - $f(-\infty)=0.0$
1882 /// - $f(\pm0.0)=1.0$
1883 ///
1884 /// See the [`Float::exp_round`] documentation for information on overflow and underflow.
1885 ///
1886 /// If you want to use a rounding mode other than `Nearest`, consider using
1887 /// [`Float::exp_round_ref`] instead. If you want to specify the output precision, consider
1888 /// using [`Float::exp_prec_ref`]. If you want both of these things, consider using
1889 /// [`Float::exp_prec_round_ref`].
1890 ///
1891 /// # Worst-case complexity
1892 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1893 ///
1894 /// $M(n) = O(n \log n)$
1895 ///
1896 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1897 ///
1898 /// # Examples
1899 /// ```
1900 /// use malachite_base::num::arithmetic::traits::Exp;
1901 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1902 /// use malachite_float::Float;
1903 ///
1904 /// assert!((&Float::NAN).exp().is_nan());
1905 /// assert_eq!((&Float::INFINITY).exp(), Float::INFINITY);
1906 /// assert_eq!((&Float::NEGATIVE_INFINITY).exp(), Float::ZERO);
1907 /// assert_eq!(
1908 /// (&Float::from_unsigned_prec(1u32, 100).0).exp().to_string(),
1909 /// "2.7182818284590452353602874713512"
1910 /// );
1911 /// ```
1912 #[inline]
1913 fn exp(self) -> Float {
1914 let prec = self.significant_bits();
1915 self.exp_prec_round_ref(prec, Nearest).0
1916 }
1917}
1918
1919impl ExpAssign for Float {
1920 /// Computes $e^x$, the exponential of a [`Float`], in place.
1921 ///
1922 /// If the output has a precision, it is the precision of the input. If the exponential is
1923 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
1924 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
1925 /// rounding mode.
1926 ///
1927 /// $$
1928 /// x \gets e^x+\varepsilon.
1929 /// $$
1930 /// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1931 /// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$,
1932 /// where $p$ is the precision of the input.
1933 ///
1934 /// See the [`Float::exp`] documentation for information on special cases, overflow, and
1935 /// underflow.
1936 ///
1937 /// If you want to use a rounding mode other than `Nearest`, consider using
1938 /// [`Float::exp_round_assign`] instead. If you want to specify the output precision, consider
1939 /// using [`Float::exp_prec_assign`]. If you want both of these things, consider using
1940 /// [`Float::exp_prec_round_assign`].
1941 ///
1942 /// # Worst-case complexity
1943 /// $T(n) = O(n^{3/2} \log n \log\log n)$
1944 ///
1945 /// $M(n) = O(n \log n)$
1946 ///
1947 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1948 ///
1949 /// # Examples
1950 /// ```
1951 /// use malachite_base::num::arithmetic::traits::ExpAssign;
1952 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1953 /// use malachite_float::Float;
1954 ///
1955 /// let mut x = Float::NAN;
1956 /// x.exp_assign();
1957 /// assert!(x.is_nan());
1958 ///
1959 /// let mut x = Float::INFINITY;
1960 /// x.exp_assign();
1961 /// assert_eq!(x, Float::INFINITY);
1962 ///
1963 /// let mut x = Float::NEGATIVE_INFINITY;
1964 /// x.exp_assign();
1965 /// assert_eq!(x, Float::ZERO);
1966 ///
1967 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1968 /// x.exp_assign();
1969 /// assert_eq!(x.to_string(), "2.7182818284590452353602874713512");
1970 /// ```
1971 #[inline]
1972 fn exp_assign(&mut self) {
1973 let prec = self.significant_bits();
1974 self.exp_prec_round_assign(prec, Nearest);
1975 }
1976}
1977
1978/// Computes $e^x$, the exponential of a primitive float. Using this function is more accurate than
1979/// using the default `exp` function or the one provided by `libm`.
1980///
1981/// $$
1982/// f(x) = e^x+\varepsilon.
1983/// $$
1984/// - If $e^x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1985/// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$, where
1986/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
1987/// [`f64`], but less if the output is subnormal).
1988///
1989/// Special cases:
1990/// - $f(\text{NaN})=\text{NaN}$
1991/// - $f(\infty)=\infty$
1992/// - $f(-\infty)=0.0$
1993/// - $f(\pm0.0)=1.0$
1994///
1995/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
1996/// `x` gives `0.0`.
1997///
1998/// # Worst-case complexity
1999/// Constant time and additional memory.
2000///
2001/// # Examples
2002/// ```
2003/// use malachite_base::num::basic::traits::NegativeInfinity;
2004/// use malachite_base::num::float::NiceFloat;
2005/// use malachite_float::float::arithmetic::exp::primitive_float_exp;
2006///
2007/// assert!(primitive_float_exp(f32::NAN).is_nan());
2008/// assert_eq!(
2009/// NiceFloat(primitive_float_exp(f32::INFINITY)),
2010/// NiceFloat(f32::INFINITY)
2011/// );
2012/// assert_eq!(
2013/// NiceFloat(primitive_float_exp(f32::NEGATIVE_INFINITY)),
2014/// NiceFloat(0.0)
2015/// );
2016/// assert_eq!(NiceFloat(primitive_float_exp(0.0f32)), NiceFloat(1.0));
2017/// assert_eq!(NiceFloat(primitive_float_exp(1.0f32)), NiceFloat(2.7182817));
2018/// ```
2019#[inline]
2020#[allow(clippy::type_repetition_in_bounds)]
2021pub fn primitive_float_exp<T: PrimitiveFloat>(x: T) -> T
2022where
2023 Float: From<T> + PartialOrd<T>,
2024 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2025{
2026 emulate_float_to_float_fn(Float::exp_prec, x)
2027}
2028
2029/// Computes $e^x$, the exponential of a [`Rational`], returning the result as a primitive float.
2030///
2031/// $$
2032/// f(x) = e^x+\varepsilon.
2033/// $$
2034/// - If $e^x$ is infinite or zero, $\varepsilon$ may be ignored or assumed to be 0.
2035/// - If $e^x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 e^x\rfloor-p}$, where
2036/// $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
2037/// [`f64`], but less if the output is subnormal).
2038///
2039/// Special cases:
2040/// - $f(0)=1$
2041///
2042/// Overflow and underflow are possible: a large positive `x` gives $\infty$, and a large negative
2043/// `x` gives `0.0`.
2044///
2045/// # Worst-case complexity
2046/// Constant time and additional memory.
2047///
2048/// # Examples
2049/// ```
2050/// use malachite_base::num::basic::traits::Zero;
2051/// use malachite_base::num::float::NiceFloat;
2052/// use malachite_float::float::arithmetic::exp::primitive_float_exp_rational;
2053/// use malachite_q::Rational;
2054///
2055/// assert_eq!(
2056/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::ZERO)),
2057/// NiceFloat(1.0)
2058/// );
2059/// assert_eq!(
2060/// NiceFloat(primitive_float_exp_rational::<f64>(
2061/// &Rational::from_unsigneds(1u8, 3)
2062/// )),
2063/// NiceFloat(1.3956124250860895)
2064/// );
2065/// assert_eq!(
2066/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::from(10000))),
2067/// NiceFloat(f64::INFINITY)
2068/// );
2069/// assert_eq!(
2070/// NiceFloat(primitive_float_exp_rational::<f64>(&Rational::from(-10000))),
2071/// NiceFloat(0.0)
2072/// );
2073/// ```
2074#[inline]
2075#[allow(clippy::type_repetition_in_bounds)]
2076pub fn primitive_float_exp_rational<T: PrimitiveFloat>(x: &Rational) -> T
2077where
2078 Float: PartialOrd<T>,
2079 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2080{
2081 emulate_rational_to_float_fn(Float::exp_rational_prec_ref, x)
2082}