summaryrefslogtreecommitdiff
path: root/mpfr/exp3.c
diff options
context:
space:
mode:
Diffstat (limited to 'mpfr/exp3.c')
-rw-r--r--mpfr/exp3.c94
1 files changed, 25 insertions, 69 deletions
diff --git a/mpfr/exp3.c b/mpfr/exp3.c
index 175ef143d..8441850b9 100644
--- a/mpfr/exp3.c
+++ b/mpfr/exp3.c
@@ -1,20 +1,20 @@
/* mpfr_exp -- exponential of a floating-point number
-Copyright (C) 1999 Free Software Foundation.
+Copyright (C) 1999, 2001 Free Software Foundation, Inc.
This file is part of the MPFR Library.
The MPFR Library is free software; you can redistribute it and/or modify
-it under the terms of the GNU Library General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at your
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The MPFR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
-You should have received a copy of the GNU Library General Public License
+You should have received a copy of the GNU Lesser General Public License
along with the MPFR Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
@@ -25,21 +25,11 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
-/* #define DEBUG */
-
-int mpfr_exp_rational _PROTO ((mpfr_ptr, mpz_srcptr, int, int));
+static int mpfr_exp_rational _PROTO ((mpfr_ptr, mpz_srcptr, int, int));
int mpfr_exp3 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
-int
-#if __STDC__
+static int
mpfr_exp_rational (mpfr_ptr y, mpz_srcptr p, int r, int m)
-#else
-mpfr_exp_rational (y, p, r, m)
- mpfr_ptr y;
- mpz_srcptr p;
- int r;
- int m;
-#endif
{
int n,i,k,j,l;
mpz_t* P,*S;
@@ -129,14 +119,7 @@ mpfr_exp_rational (y, p, r, m)
#define shift (BITS_PER_MP_LIMB/2)
int
-#if __STDC__
mpfr_exp3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
-#else
-mpfr_exp3 (y, x, rnd_mode)
- mpfr_ptr y;
- mpfr_srcptr x;
- mp_rnd_t rnd_mode;
-#endif
{
mpfr_t t;
mpfr_t x_copy;
@@ -152,27 +135,10 @@ mpfr_exp3 (y, x, rnd_mode)
int good = 0;
int realprec = 0;
int iter;
- int logn;
-
- /* commencons par 0 */
- if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); return 1; }
-
- if (MPFR_IS_INF(x))
- {
- if (MPFR_SIGN(x) > 0)
- { MPFR_SET_INF(y); if (MPFR_SIGN(y) == -1) { MPFR_CHANGE_SIGN(y); } }
- else
- { MPFR_SET_ZERO(y); if (MPFR_SIGN(y) == -1) { MPFR_CHANGE_SIGN(y); } }
- /* TODO: conflits entre infinis et zeros ? */
- }
-
- if (!MPFR_NOTZERO(x)) {
- mpfr_set_ui(y, 1, GMP_RNDN);
- return 0;
- }
+ int logn, inexact = 0;
- /* Decomposer x */
- /* on commence par ecrire x = 1.xxxxxxxxxxxxx
+ /* decompose x */
+ /* we first write x = 1.xxxxxxxxxxxxx
----- k bits -- */
prec_x = _mpfr_ceil_log2 ((double) (MPFR_PREC(x)) / BITS_PER_MP_LIMB);
if (prec_x < 0) prec_x = 0;
@@ -181,7 +147,7 @@ mpfr_exp3 (y, x, rnd_mode)
ttt = MPFR_EXP(x);
mpfr_init2(x_copy,MPFR_PREC(x));
mpfr_set(x_copy,x,GMP_RNDD);
- /* on fait le shift pour que le nombre soit inferieur a 1 */
+ /* we shift to get a number less than 1 */
if (ttt > 0)
{
shift_x = ttt;
@@ -195,52 +161,42 @@ mpfr_exp3 (y, x, rnd_mode)
k = _mpfr_ceil_log2 ((double) Prec / BITS_PER_MP_LIMB);
/* now we have to extract */
- mpfr_init2(t, Prec);
- mpfr_init2(tmp, Prec);
+ mpfr_init2 (t, Prec);
+ mpfr_init2 (tmp, Prec);
mpfr_set_ui(tmp,1,GMP_RNDN);
twopoweri = BITS_PER_MP_LIMB;
if (k <= prec_x) iter = k; else iter= prec_x;
for(i = 0; i <= iter; i++){
mpfr_extract (uk, x_copy, i);
-#ifdef DEBUG
- mpz_out_str(stderr,2, uk);
- fprintf(stderr, "---\n");
- fprintf(stderr, "---%d\n", twopoweri - ttt);
-#endif
if (i)
mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1);
else
{
- /* cas particulier : on est oblige de faire les calculs avec x/2^.
- puis elever au carre (plus rapide) */
+ /* particular case: we have to compute with x/2^., then
+ do squarings (this is faster) */
mpfr_exp_rational (t, uk, shift + twopoweri - ttt, k+1);
for (loop= 0 ; loop < shift; loop++)
mpfr_mul(t,t,t,GMP_RNDD);
}
mpfr_mul(tmp,tmp,t,GMP_RNDD);
-#ifdef DEBUG
- fprintf(stderr, "fin\n");
- mpfr_out_str(stderr, 2, MPFR_PREC(y), t, GMP_RNDD);
- fprintf(stderr, "\n ii --- ii \n");
-#endif
twopoweri <<= 1;
}
+ mpfr_clear (t);
for (loop= 0 ; loop < shift_x; loop++)
- mpfr_mul(tmp,tmp,tmp,GMP_RNDD);
- mpfr_clear(t);
- if (mpfr_can_round(tmp, realprec, GMP_RNDD, rnd_mode, MPFR_PREC(y))){
- mpfr_set(y,tmp,rnd_mode);
- mpfr_clear(tmp);
- good = 1;
- } else {
- mpfr_clear(tmp);
+ mpfr_mul (tmp, tmp, tmp, GMP_RNDD);
+ if (mpfr_can_round (tmp, realprec, GMP_RNDD, rnd_mode, MPFR_PREC(y)))
+ {
+ inexact = mpfr_set (y, tmp, rnd_mode);
+ good = 1;
+ }
+ else
realprec += 3*logn;
- }
+ mpfr_clear (tmp);
}
mpz_clear (uk);
mpfr_clear(x_copy);
- return 0;
+ return inexact;
}