1
/* mpfr_exp -- exponential of a floating-point number
3
Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
5
This file is part of the MPFR Library.
7
The MPFR Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The MPFR Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the MPFR Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
MA 02111-1307, USA. */
26
#include "mpfr-impl.h"
28
static int mpfr_exp_rational _PROTO ((mpfr_ptr, mpz_srcptr, int, int));
31
mpfr_exp_rational (mpfr_ptr y, mpz_srcptr p, int r, int m)
37
int precy = MPFR_PREC(y);
46
P = (mpz_t*) TMP_ALLOC((m+1) * sizeof(mpz_t));
47
S = (mpz_t*) TMP_ALLOC((m+1) * sizeof(mpz_t));
48
ptoj = (mpz_t*) TMP_ALLOC((m+1) * sizeof(mpz_t)); /* ptoj[i] = mantissa^(2^i) */
49
mult = (int*) TMP_ALLOC((m+1) * sizeof(int));
50
nb_terms = (int*) TMP_ALLOC((m+1) * sizeof(int));
52
for (i=0;i<=m;i++) { mpz_init(P[i]); mpz_init(S[i]); mpz_init(ptoj[i]); }
54
for (i=1;i<m;i++) mpz_mul(ptoj[i], ptoj[i-1], ptoj[i-1]);
60
for (i=1;(prec_i_have < precy) && (i < n) ;i++) {
63
mpz_set_ui(P[k], i+1);
65
j=i+1; l=0; while ((j & 1) == 0) {
66
mpz_mul(S[k], S[k], ptoj[l]);
67
mpz_mul(S[k-1], S[k-1], P[k]);
68
mpz_mul_2exp(S[k-1], S[k-1], r*(1<<l));
69
mpz_add(S[k-1], S[k-1], S[k]);
70
mpz_mul(P[k-1], P[k-1], P[k]);
71
nb_terms[k-1] = nb_terms[k-1]+ nb_terms[k];
72
mult[k] = mult[k-1] + (1 << l)*(r >> 2) + mpz_sizeinbase(P[k],2) - 1;
73
prec_i_have = mult[k];
80
mpz_mul(S[k], S[k], ptoj[_mpfr_ceil_log2((double) nb_terms[k])]);
81
mpz_mul(S[k-1], S[k-1], P[k]);
83
mpz_mul_2exp(S[k-1], S[k-1], r* accu);
84
mpz_add(S[k-1], S[k-1], S[k]);
85
mpz_mul(P[k-1], P[k-1], P[k]);
89
diff = mpz_sizeinbase(S[0],2) - 2*precy;
93
mpz_div_2exp(S[0],S[0],diff);
96
mpz_mul_2exp(S[0],S[0],-diff);
98
diff = mpz_sizeinbase(P[0],2) - precy;
102
mpz_div_2exp(P[0],P[0],diff);
105
mpz_mul_2exp(P[0],P[0],-diff);
108
mpz_tdiv_q(S[0], S[0], P[0]);
109
mpfr_set_z(y,S[0], GMP_RNDD);
112
mpfr_div_2ui(y, y, r*(i-1),GMP_RNDN);
113
for (i=0;i<=m;i++) { mpz_clear(P[i]); mpz_clear(S[i]); mpz_clear(ptoj[i]); }
118
#define shift (BITS_PER_MP_LIMB/2)
121
mpfr_exp3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
137
int logn, inexact = 0;
140
/* we first write x = 1.xxxxxxxxxxxxx
142
prec_x = _mpfr_ceil_log2 ((double) (MPFR_PREC(x)) / BITS_PER_MP_LIMB);
143
if (prec_x < 0) prec_x = 0;
144
logn = _mpfr_ceil_log2 ((double) prec_x + MPFR_PREC(y));
145
if (logn < 2) logn = 2;
147
mpfr_init2(x_copy,MPFR_PREC(x));
148
mpfr_set(x_copy,x,GMP_RNDD);
149
/* we shift to get a number less than 1 */
153
mpfr_div_2ui(x_copy, x, ttt, GMP_RNDN);
154
ttt = MPFR_EXP(x_copy);
156
realprec = MPFR_PREC(y)+logn;
159
Prec = realprec+shift+2+shift_x;
160
k = _mpfr_ceil_log2 ((double) Prec / BITS_PER_MP_LIMB);
162
/* now we have to extract */
163
mpfr_init2 (t, Prec);
164
mpfr_init2 (tmp, Prec);
165
mpfr_set_ui(tmp,1,GMP_RNDN);
166
twopoweri = BITS_PER_MP_LIMB;
167
if (k <= prec_x) iter = k; else iter= prec_x;
168
for(i = 0; i <= iter; i++){
169
mpfr_extract (uk, x_copy, i);
171
mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1);
174
/* particular case: we have to compute with x/2^., then
175
do squarings (this is faster) */
176
mpfr_exp_rational (t, uk, shift + twopoweri - ttt, k+1);
177
for (loop= 0 ; loop < shift; loop++)
178
mpfr_mul(t,t,t,GMP_RNDD);
181
mpfr_mul(tmp,tmp,t,GMP_RNDD);
185
for (loop= 0 ; loop < shift_x; loop++)
186
mpfr_mul (tmp, tmp, tmp, GMP_RNDD);
187
if (mpfr_can_round (tmp, realprec, GMP_RNDD, rnd_mode, MPFR_PREC(y)))
189
inexact = mpfr_set (y, tmp, rnd_mode);