diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-10 15:43:41 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-10 15:43:41 +0000 |
commit | 667b2763ad6e7b02174303e6646e49f37e80a677 (patch) | |
tree | 820dfe4fc5f18fec632e9ee60ada8d3add40b89b | |
parent | a9c75f5b66a8b6379b0c8d4782949ba935cb86c8 (diff) | |
download | mpfr-667b2763ad6e7b02174303e6646e49f37e80a677.tar.gz |
Add log for other functions.
Add ZivLoop too.
Cleanup exp3.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3290 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | cosh.c | 16 | ||||
-rw-r--r-- | exp.c | 64 | ||||
-rw-r--r-- | exp3.c | 98 | ||||
-rw-r--r-- | exp_2.c | 7 | ||||
-rw-r--r-- | log.c | 10 | ||||
-rw-r--r-- | sin_cos.c | 8 | ||||
-rw-r--r-- | sinh.c | 13 | ||||
-rw-r--r-- | tan.c | 10 | ||||
-rw-r--r-- | tanh.c | 21 |
9 files changed, 145 insertions, 102 deletions
@@ -53,6 +53,8 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) } } + MPFR_LOG_BEGIN (("x[%#R]=%R rnd=%d", x, x, rnd_mode)); + MPFR_SAVE_EXPO_MARK (expo); MPFR_TMP_INIT_ABS(x, xt); @@ -67,9 +69,10 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mp_prec_t Nt; /* Precision of the intermediary variable */ long int err; /* Precision of error */ - + MPFR_ZIV_DECL (loop); + /* compute the precision of intermediary variable */ - Nt = MAX(Nx, Ny); + Nt = MAX (Nx, Ny); /* The optimal number of bits : see algorithms.ps */ Nt = Nt + 3 + MPFR_INT_CEIL_LOG2 (Nt); @@ -78,6 +81,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mpfr_init2 (te, Nt); /* First computation of cosh */ + MPFR_ZIV_INIT (loop, Nt); for (;;) { /* Compute cosh */ @@ -96,11 +100,11 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) break; /* Actualisation of the precision */ - Nt += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, Nt); mpfr_set_prec (t, Nt); mpfr_set_prec (te, Nt); } - + MPFR_ZIV_FREE (loop); inexact = mpfr_set (y, t, rnd_mode); mpfr_clear (te); @@ -108,5 +112,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) } MPFR_SAVE_EXPO_FREE (expo); - return mpfr_check_range (y, inexact, rnd_mode); + inexact = mpfr_check_range (y, inexact, rnd_mode); + MPFR_LOG_END (("y[%#R]=%R inexact=%d", y, y, rnd_mode)); + return inexact; } @@ -60,6 +60,7 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) } } MPFR_CLEAR_FLAGS(y); + MPFR_LOG_BEGIN (("x[%#R]=%R rnd=%d", x, x, rnd_mode)); expx = MPFR_GET_EXP (x); precy = MPFR_PREC (y); @@ -69,48 +70,59 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) /* TODO: Don't convert to double! */ d = mpfr_get_d1 (x); if (MPFR_UNLIKELY (d >= (double) __gmpfr_emax * LOG2)) - return mpfr_overflow (y, rnd_mode, 1); + inexact = mpfr_overflow (y, rnd_mode, 1); /* result is 0 when exp(x) < 1/2*2^(__gmpfr_emin), i.e. x < (__gmpfr_emin-1) * LOG2 */ - if (MPFR_UNLIKELY(d < ((double) __gmpfr_emin - 1.0) * LOG2)) + else if (MPFR_UNLIKELY(d < ((double) __gmpfr_emin - 1.0) * LOG2)) { /* warning: mpfr_underflow rounds away for RNDN */ if (rnd_mode == GMP_RNDN && d < ((double) __gmpfr_emin - 2.0) * LOG2) rnd_mode = GMP_RNDZ; - return mpfr_underflow (y, rnd_mode, 1); + inexact = mpfr_underflow (y, rnd_mode, 1); } /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */ - if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy)) + else if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy)) { - int signx = MPFR_SIGN(x); + int signx = MPFR_SIGN (x); - MPFR_SET_POS(y); - if (MPFR_IS_NEG_SIGN(signx) && rnd_mode == GMP_RNDD) + MPFR_SET_POS (y); + if (MPFR_IS_NEG_SIGN (signx) && rnd_mode == GMP_RNDD) { mpfr_setmax (y, 0); /* y = 1 - epsilon */ - return -1; + inexact = -1; } - mpfr_setmin (y, 1); /* y = 1 */ - if (MPFR_IS_POS_SIGN(signx) && rnd_mode == GMP_RNDU) - { - mp_size_t yn; - int sh; + else + { + mpfr_setmin (y, 1); /* y = 1 */ + if (MPFR_IS_POS_SIGN (signx) && rnd_mode == GMP_RNDU) + { + mp_size_t yn; + int sh; + + yn = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB; + sh = (mp_prec_t) yn * BITS_PER_MP_LIMB - MPFR_PREC(y); + MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh; + inexact = 1; + } + else + inexact = -MPFR_FROM_SIGN_TO_INT(signx); + } + } - yn = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB; - sh = (mp_prec_t) yn * BITS_PER_MP_LIMB - MPFR_PREC(y); - MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh; - return 1; - } - return -MPFR_FROM_SIGN_TO_INT(signx); + /* General case */ + else + { + MPFR_SAVE_EXPO_MARK (expo); + if (MPFR_UNLIKELY (precy > MPFR_EXP_THRESHOLD)) + inexact = mpfr_exp_3 (y, x, rnd_mode); /* O(M(n) log(n)^2) */ + else + inexact = mpfr_exp_2 (y, x, rnd_mode); /* O(n^(1/3) M(n)) */ + MPFR_SAVE_EXPO_FREE (expo); + inexact = mpfr_check_range (y, inexact, rnd_mode); } - MPFR_SAVE_EXPO_MARK (expo); - if (MPFR_UNLIKELY (precy > MPFR_EXP_THRESHOLD)) - inexact = mpfr_exp_3 (y, x, rnd_mode); /* O(M(n) log(n)^2) */ - else - inexact = mpfr_exp_2 (y, x, rnd_mode); /* O(n^(1/3) M(n)) */ - MPFR_SAVE_EXPO_FREE (expo); - return mpfr_check_range (y, inexact, rnd_mode); + MPFR_LOG_END (("y[%#R]=%R inexact=%d", y, y, inexact)); + return inexact; } @@ -1,6 +1,6 @@ /* mpfr_exp -- exponential of a floating-point number -Copyright 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +Copyright 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -144,21 +144,16 @@ mpfr_exp_rational (mpfr_ptr y, mpz_srcptr p, int r, int m) int mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { - mpfr_t t; - mpfr_t x_copy; - int i, k; + mpfr_t t, x_copy, tmp; + int i, k, loop; mpz_t uk; - mpfr_t tmp; - int ttt; - int twopoweri; - int Prec; - int loop; + mp_exp_t ttt, shift_x; + unsigned long twopoweri; int prec_x; - int shift_x = 0; - int good = 0; - int realprec = 0; + mp_prec_t realprec, Prec; int iter; - int logn, inexact = 0; + int inexact = 0; + MPFR_ZIV_DECL (ziv_loop); /* decompose x */ /* we first write x = 1.xxxxxxxxxxxxx @@ -168,10 +163,6 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (prec_x < 0) prec_x = 0; - logn = MPFR_INT_CEIL_LOG2 (prec_x + MPFR_PREC (y)); - if (logn < 2) - logn = 2; - ttt = MPFR_GET_EXP (x); mpfr_init2 (x_copy, MPFR_PREC(x)); mpfr_set (x_copy, x, GMP_RNDD); @@ -183,55 +174,58 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_div_2ui (x_copy, x, ttt, GMP_RNDN); ttt = MPFR_GET_EXP (x_copy); } - MPFR_ASSERTD(ttt <= 0); - - /* the following code assumes BITS_PER_MP_LIMB is a power of two */ - MPFR_ASSERTN((BITS_PER_MP_LIMB & (BITS_PER_MP_LIMB - 1)) == 0); - - realprec = MPFR_PREC(y) + logn; + else + shift_x = 0; + MPFR_ASSERTD (ttt <= 0); + + /* Init prec and vars */ + realprec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (prec_x + MPFR_PREC (y)); + Prec = realprec + shift + 2 + shift_x; + mpfr_init2 (t, Prec); + mpfr_init2 (tmp, Prec); mpz_init (uk); - while (!good) + + /* Main loop */ + MPFR_ZIV_INIT (ziv_loop, realprec); + for (;;) { - Prec = realprec + shift + 2 + shift_x; k = __gmpfr_ceil_log2 ((double) Prec / BITS_PER_MP_LIMB); /* now we have to extract */ - mpfr_init2 (t, Prec); - mpfr_init2 (tmp, Prec); - mpfr_set_ui (tmp, 1, GMP_RNDN); twopoweri = BITS_PER_MP_LIMB; + + /* Particular case for i==0 */ + mpfr_extract (uk, x_copy, 0); + mpfr_exp_rational (tmp, uk, shift + twopoweri - ttt, k + 1); + for (loop = 0 ; loop < shift; loop++) + mpfr_mul (tmp, tmp, tmp, GMP_RNDD); + twopoweri *=2; + + /* General case */ iter = (k <= prec_x) ? k : prec_x; - for (i = 0; i <= iter; i++) + for (i = 1 ; i <= iter; i++) { mpfr_extract (uk, x_copy, i); - if (i) - mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1); - else - { - /* 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); - MPFR_ASSERTN(twopoweri <= INT_MAX/2); - twopoweri <<= 1; + mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1); + mpfr_mul (tmp, tmp, t, GMP_RNDD); + MPFR_ASSERTN (twopoweri <= INT_MAX/2); + twopoweri *=2; } - mpfr_clear (t); for (loop = 0 ; loop < shift_x; loop++) mpfr_mul (tmp, tmp, tmp, GMP_RNDD); + if (mpfr_can_round (tmp, realprec, GMP_RNDD, GMP_RNDZ, MPFR_PREC(y) + (rnd_mode == GMP_RNDN))) - { - inexact = mpfr_set (y, tmp, rnd_mode); - good = 1; - } - else - realprec += 3 * logn; - mpfr_clear (tmp); - } + break; + MPFR_ZIV_NEXT (ziv_loop, realprec); + Prec = realprec + shift + 2 + shift_x; + mpfr_set_prec (t, Prec); + mpfr_set_prec (tmp, Prec); + } + MPFR_ZIV_FREE (ziv_loop); + inexact = mpfr_set (y, tmp, rnd_mode); + mpfr_clear (tmp); + mpfr_clear (t); mpz_clear (uk); mpfr_clear (x_copy); return inexact; @@ -91,6 +91,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) int inexact; mpfr_t r, s, t; mpz_t ss; + MPFR_ZIV_DECL (loop); TMP_DECL(marker); precy = MPFR_PREC(y); @@ -126,6 +127,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) /* the algorithm consists in computing an upper bound of exp(x) using a precision of q bits, and see if we can round to MPFR_PREC(y) taking into account the maximal error. Otherwise we increase q. */ + MPFR_ZIV_INIT (loop, q); for (;;) { MPFR_TRACE ( printf("n=%d K=%d l=%d q=%d\n",n,K,l,q) ); @@ -192,12 +194,13 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) break; MPFR_TRACE (printf("prec++, use %d\n", q+BITS_PER_MP_LIMB) ); MPFR_TRACE (printf("q=%d q-K=%d precy=%d\n",q,q-K,precy) ); - q += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, q); mpfr_set_prec (r, q); mpfr_set_prec (s, q); mpfr_set_prec (t, q); } - + MPFR_ZIV_FREE (loop); + inexact = mpfr_set (y, s, rnd_mode); mpfr_clear (r); @@ -1,6 +1,6 @@ /* mpfr_log -- natural logarithm of a floating-point number -Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation. +Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation. This file is part of the MPFR Library. @@ -49,6 +49,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) mp_prec_t p, q; mpfr_t tmp1, tmp2; mp_limb_t *tmp1p, *tmp2p; + MPFR_ZIV_DECL (loop); TMP_DECL(marker); /* Special cases */ @@ -100,6 +101,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) MPFR_RET (0); /* only "normal" case where the result is exact */ } MPFR_CLEAR_FLAGS (r); + MPFR_LOG_BEGIN (("a[%#R]=%R rnd=%d", a, a, rnd_mode)); q = MPFR_PREC (r); @@ -112,6 +114,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) TMP_MARK(marker); + MPFR_ZIV_INIT (loop, p); for (;;) { mp_size_t size; @@ -152,11 +155,14 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) if (mpfr_can_round (tmp1, p - cancel - 4, GMP_RNDN, GMP_RNDZ, q + (rnd_mode == GMP_RNDN))) break; - p += BITS_PER_MP_LIMB + cancel; + p += cancel; + MPFR_ZIV_NEXT (loop, p); } + MPFR_ZIV_FREE (loop); inexact = mpfr_set (r, tmp1, rnd_mode); /* We clean */ TMP_FREE(marker); + MPFR_LOG_END (("r[%#R]=%R inexact=%d", r, r, inexact)); return inexact; /* result is inexact */ } @@ -30,6 +30,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode) int prec, m, neg; mpfr_t c, k; mp_exp_t e; + MPFR_ZIV_DECL (loop); if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) { @@ -48,7 +49,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_RET (0); } } - /* MPFR_CLEAR_FLAGS is useless since we use mpfr_set to set y and z */ + MPFR_LOG_BEGIN (("x[%#R]=%R rnd=%d", x, x, rnd_mode)); prec = MAX (MPFR_PREC (y), MPFR_PREC (z)); m = prec + MPFR_INT_CEIL_LOG2 (prec) + 13; @@ -74,6 +75,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode) else neg = MPFR_SIGN (x) < 0; + MPFR_ZIV_INIT (loop, m); for (;;) { mpfr_cos (c, x, GMP_RNDZ); @@ -100,13 +102,15 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode) m = 2*m; next_step: - m += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, m); mpfr_set_prec (c, m); } + MPFR_ZIV_FREE (loop); mpfr_set (y, c, rnd_mode); mpfr_clear (c); + MPFR_LOG_END (("sin[%#R]=%R cos[%#R]=%R", y, y, z, z)); MPFR_RET (1); /* Always inexact */ } @@ -52,7 +52,8 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) MPFR_RET(0); } } - + MPFR_LOG_BEGIN (("x[%#R]=%R rnd=%d", x, x, rnd_mode)); + MPFR_TMP_INIT_ABS (x, xt); { @@ -60,6 +61,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) mp_exp_t d; mp_prec_t Nt; /* Precision of the intermediary variable */ long int err; /* Precision of error */ + MPFR_ZIV_DECL (loop); int overflow_p = mpfr_overflow_p (); /* compute the precision of intermediary variable */ @@ -75,6 +77,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) mpfr_init2 (ti, Nt); /* First computation of sinh */ + MPFR_ZIV_INIT (loop, Nt); for (;;) { /* compute sinh */ mpfr_clear_overflow (); @@ -105,11 +108,12 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) break; } /* actualisation of the precision */ - Nt += MAX (BITS_PER_MP_LIMB, err); + Nt += err; + MPFR_ZIV_NEXT (loop, Nt); mpfr_set_prec (t, Nt); mpfr_set_prec (ti, Nt); } - + MPFR_ZIV_FREE (loop); inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt)); if (overflow_p != 0) __gmpfr_flags |= MPFR_FLAGS_OVERFLOW; @@ -117,6 +121,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) mpfr_clear (t); mpfr_clear (ti); } - + MPFR_LOG_END (("y[%#R]=%R inexact=%d", y, y, inexact)); + return inexact; } @@ -1,6 +1,6 @@ /* mpfr_tan -- tangent of a floating-point number -Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -28,6 +28,7 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { int precy, m, inexact; mpfr_t s, c; + MPFR_ZIV_DECL (loop); if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x))) { @@ -44,6 +45,7 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_RET(0); } } + MPFR_LOG_BEGIN (("x[%#R]=%R rnd=%d", x, x, rnd_mode)); precy = MPFR_PREC (y); m = precy + MPFR_INT_CEIL_LOG2 (precy) + 13; @@ -55,6 +57,7 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_init2 (s, m); mpfr_init2 (c, m); + MPFR_ZIV_INIT (loop, m); for (;;) { mpfr_sin_cos (s, c, x, GMP_RNDN); /* err <= 1/2 ulp on s and c */ @@ -62,15 +65,18 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_INF(x) || mpfr_can_round (c, m - 1, GMP_RNDN, GMP_RNDZ, precy + (rnd_mode == GMP_RNDN))) break; - m += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, m); mpfr_set_prec (s, m); mpfr_set_prec (c, m); } + MPFR_ZIV_FREE (loop); inexact = mpfr_set (y, c, rnd_mode); mpfr_clear (s); mpfr_clear (c); + MPFR_LOG_END (("y[%#R]=%R inexact=%d", y, y, inexact)); + return inexact; } @@ -52,6 +52,8 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) } } + MPFR_LOG_BEGIN (("x[%#R]=%R rnd_mode=%d", x, x, rnd_mode)); + MPFR_SAVE_EXPO_MARK (expo); MPFR_TMP_INIT_ABS (x, xt); @@ -66,7 +68,8 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mp_prec_t Ny = MPFR_PREC(y); /* Precision of output variable */ mp_prec_t Nt; /* Precision of intermediary variables */ long int err; /* Precision of error */ - + MPFR_ZIV_DECL (loop); + /* Compute the precision of intermediary variable */ Nt = MAX (Nx, Ny); @@ -76,7 +79,8 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) /* initialise of intermediary variable */ mpfr_init2 (t, Nt); mpfr_init2 (te, Nt); - + + MPFR_ZIV_INIT (loop, Nt); if (MPFR_GET_EXP (x) > 10) for (;;) { /* tanh(x)=1-2/(exp(2x)+1) */ @@ -88,7 +92,7 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) d = MPFR_GET_EXP (t); mpfr_ui_sub (t, 1, t, GMP_RNDZ); /*1-2/(exp(2x)+1) */ - /* Calculation of the error*/ + /* Calculation of the error */ /* err (t) <= (1+8*2^(d-EXP(t)))*ulp(t) */ d = d - MPFR_GET_EXP (t); err = Nt - MAX (d + 4, 1); @@ -98,7 +102,7 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) break; /* Actualisation of the precision */ - Nt += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, Nt); mpfr_set_prec (t, Nt); mpfr_set_prec (te, Nt); } @@ -121,16 +125,19 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) break; /* Actualisation of the precision */ - Nt += BITS_PER_MP_LIMB; + MPFR_ZIV_NEXT (loop, Nt); mpfr_set_prec (t, Nt); mpfr_set_prec (te, Nt); } - + MPFR_ZIV_FREE (loop); inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt)); mpfr_clear (te); mpfr_clear (t); } MPFR_SAVE_EXPO_FREE (expo); - return mpfr_check_range (y, inexact, rnd_mode); + inexact = mpfr_check_range (y, inexact, rnd_mode); + + MPFR_LOG_END (("y[%#R]=%R inexact=%d", y, y, inexact)); + return inexact; } |