diff -Naurd mpfr-2.2.1/VERSION mpfr-2.2.1-p1/VERSION --- mpfr-2.2.1/VERSION 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p1/VERSION 2007-02-02 00:01:41.000000000 +0000 @@ -1 +1 @@ -2.2.1 +2.2.1-p1 diff -Naurd mpfr-2.2.1/mpfr.h mpfr-2.2.1-p1/mpfr.h --- mpfr-2.2.1/mpfr.h 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p1/mpfr.h 2007-02-02 00:01:41.000000000 +0000 @@ -26,7 +26,7 @@ #define MPFR_VERSION_MAJOR 2 #define MPFR_VERSION_MINOR 2 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "2.2.1" +#define MPFR_VERSION_STRING "2.2.1-p1" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) @@ -680,6 +680,8 @@ ( mpfr_init(x), mpfr_set_ui((x), (i), (rnd)) ) #define mpfr_init_set_d(x, d, rnd) \ ( mpfr_init(x), mpfr_set_d((x), (d), (rnd)) ) +#define mpfr_init_set_ld(x, d, rnd) \ + ( mpfr_init(x), mpfr_set_ld((x), (d), (rnd)) ) #define mpfr_init_set_z(x, i, rnd) \ ( mpfr_init(x), mpfr_set_z((x), (i), (rnd)) ) #define mpfr_init_set_q(x, i, rnd) \ diff -Naurd mpfr-2.2.1/tests/tversion.c mpfr-2.2.1-p1/tests/tversion.c --- mpfr-2.2.1/tests/tversion.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p1/tests/tversion.c 2007-02-02 00:01:41.000000000 +0000 @@ -45,7 +45,7 @@ version = mpfr_get_version (); /* This test is disabled when a suffix (e.g. -dev) has been defined. */ -#if 1 +#if 0 sprintf (buffer, "%d.%d.%d", MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL); if (strcmp (buffer, version) != 0) diff -Naurd mpfr-2.2.1/version.c mpfr-2.2.1-p1/version.c --- mpfr-2.2.1/version.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p1/version.c 2007-02-02 00:01:41.000000000 +0000 @@ -24,5 +24,5 @@ const char * mpfr_get_version (void) { - return "2.2.1"; + return "2.2.1-p1"; } diff -Naurd mpfr-2.2.1-p1/VERSION mpfr-2.2.1-p2/VERSION --- mpfr-2.2.1-p1/VERSION 2007-02-02 00:01:41.000000000 +0000 +++ mpfr-2.2.1-p2/VERSION 2007-02-15 23:37:58.000000000 +0000 @@ -1 +1 @@ -2.2.1-p1 +2.2.1-p2 diff -Naurd mpfr-2.2.1-p1/mpfr.h mpfr-2.2.1-p2/mpfr.h --- mpfr-2.2.1-p1/mpfr.h 2007-02-02 00:01:41.000000000 +0000 +++ mpfr-2.2.1-p2/mpfr.h 2007-02-15 23:37:58.000000000 +0000 @@ -26,7 +26,7 @@ #define MPFR_VERSION_MAJOR 2 #define MPFR_VERSION_MINOR 2 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "2.2.1-p1" +#define MPFR_VERSION_STRING "2.2.1-p2" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) diff -Naurd mpfr-2.2.1-p1/tests/tget_f.c mpfr-2.2.1-p2/tests/tget_f.c --- mpfr-2.2.1-p1/tests/tget_f.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p2/tests/tget_f.c 2007-02-15 23:37:53.000000000 +0000 @@ -153,8 +153,9 @@ } if (i <= - (unsigned long) LONG_MIN) { - mpfr_set_si (y, - (long) i, GMP_RNDN); - if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_si (x, - (long) i)) + long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN; + mpfr_set_si (y, j, GMP_RNDN); + if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_si (x, j)) { printf ("Error: mpfr_get_f(-%lu) fails\n", i); exit (1); diff -Naurd mpfr-2.2.1-p1/version.c mpfr-2.2.1-p2/version.c --- mpfr-2.2.1-p1/version.c 2007-02-02 00:01:41.000000000 +0000 +++ mpfr-2.2.1-p2/version.c 2007-02-15 23:37:58.000000000 +0000 @@ -24,5 +24,5 @@ const char * mpfr_get_version (void) { - return "2.2.1-p1"; + return "2.2.1-p2"; } diff -Naurd mpfr-2.2.1-p2/VERSION mpfr-2.2.1-p3/VERSION --- mpfr-2.2.1-p2/VERSION 2007-02-15 23:37:58.000000000 +0000 +++ mpfr-2.2.1-p3/VERSION 2007-02-15 23:40:49.000000000 +0000 @@ -1 +1 @@ -2.2.1-p2 +2.2.1-p3 diff -Naurd mpfr-2.2.1-p2/mpfr.h mpfr-2.2.1-p3/mpfr.h --- mpfr-2.2.1-p2/mpfr.h 2007-02-15 23:37:58.000000000 +0000 +++ mpfr-2.2.1-p3/mpfr.h 2007-02-15 23:40:49.000000000 +0000 @@ -26,7 +26,7 @@ #define MPFR_VERSION_MAJOR 2 #define MPFR_VERSION_MINOR 2 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "2.2.1-p2" +#define MPFR_VERSION_STRING "2.2.1-p3" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) @@ -626,13 +626,13 @@ _p->_mpfr_sign = 1; \ _p->_mpfr_exp = __MPFR_EXP_ZERO; \ (void) (_r); 0; }) : \ - mpfr_set_ui (_f,_u,_r)) + mpfr_set_ui_2exp ((_f), (_u), 0, (_r))) #endif #undef mpfr_set_si #define mpfr_set_si(_f,_s,_r) \ (__builtin_constant_p (_s) && (_s) >= 0 ? \ mpfr_set_ui ((_f), (_s), (_r)) : \ - mpfr_set_si ((_f), (_s), (_r))) + mpfr_set_si_2exp ((_f), (_s), 0, (_r))) #endif #endif diff -Naurd mpfr-2.2.1-p2/set_si.c mpfr-2.2.1-p3/set_si.c --- mpfr-2.2.1-p2/set_si.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p3/set_si.c 2007-02-15 23:40:22.000000000 +0000 @@ -19,62 +19,11 @@ the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define MPFR_NEED_LONGLONG_H #include "mpfr-impl.h" +#undef mpfr_set_si int -(mpfr_set_si) (mpfr_ptr x, long i, mp_rnd_t rnd_mode) +mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode) { - int inex; - mp_size_t xn; - unsigned int cnt, nbits; - mp_limb_t ai, *xp; - - MPFR_CLEAR_FLAGS(x); - if (i == 0) - { - MPFR_SET_ZERO(x); - MPFR_SET_POS(x); - MPFR_RET(0); - } - - xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB; - ai = SAFE_ABS(unsigned long, i); - MPFR_ASSERTN(SAFE_ABS(unsigned long, i) == ai); - count_leading_zeros(cnt, ai); - - xp = MPFR_MANT(x); - xp[xn] = ai << cnt; - /* don't forget to put zero in lower limbs */ - MPN_ZERO(xp, xn); - /* set sign */ - if (i < 0) - MPFR_SET_NEG(x); - else - MPFR_SET_POS(x); - - nbits = BITS_PER_MP_LIMB - cnt; - MPFR_EXP (x) = nbits; /* may be out-of-range, check range below */ - inex = mpfr_check_range(x, 0, rnd_mode); - if (inex) - return inex; /* underflow or overflow */ - - /* round if MPFR_PREC(x) smaller than length of i */ - if (MPFR_UNLIKELY(MPFR_PREC(x) < nbits)) - { - int carry; - - carry = mpfr_round_raw(xp+xn, xp+xn, nbits, (i < 0), MPFR_PREC(x), - rnd_mode, &inex); - if (MPFR_UNLIKELY(carry)) - { - /* nbits is the current exponent */ - if (MPFR_UNLIKELY((mp_exp_t) nbits == __gmpfr_emax)) - return mpfr_overflow(x, rnd_mode, (i < 0 ? -1 : 1)); - MPFR_SET_EXP (x, nbits + 1); - xp[xn] = MPFR_LIMB_HIGHBIT; - } - } - - MPFR_RET(inex); + return mpfr_set_si_2exp (x, i, 0, rnd_mode); } diff -Naurd mpfr-2.2.1-p2/set_si_2exp.c mpfr-2.2.1-p3/set_si_2exp.c --- mpfr-2.2.1-p2/set_si_2exp.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p3/set_si_2exp.c 2007-02-15 23:40:22.000000000 +0000 @@ -20,18 +20,54 @@ the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define MPFR_NEED_LONGLONG_H #include "mpfr-impl.h" int mpfr_set_si_2exp (mpfr_ptr x, long i, mp_exp_t e, mp_rnd_t rnd_mode) { - int res; - MPFR_SAVE_EXPO_DECL (expo); + if (i == 0) + { + MPFR_SET_ZERO (x); + MPFR_SET_POS (x); + MPFR_RET (0); + } + else + { + mp_size_t xn; + unsigned int cnt, nbits; + mp_limb_t ai, *xp; + int inex = 0; - MPFR_SAVE_EXPO_MARK (expo); - res = mpfr_set_si (x, i, rnd_mode); - mpfr_mul_2si (x, x, e, rnd_mode); /* Should be exact */ - MPFR_SAVE_EXPO_FREE (expo); - res = mpfr_check_range(x, res, rnd_mode); - return res; + /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */ + ai = SAFE_ABS (unsigned long, i); + MPFR_ASSERTN (SAFE_ABS (unsigned long, i) == ai); + + /* Position of the highest limb */ + xn = (MPFR_PREC (x) - 1) / BITS_PER_MP_LIMB; + count_leading_zeros (cnt, ai); + MPFR_ASSERTD (cnt < BITS_PER_MP_LIMB); /* OK since i != 0 */ + + xp = MPFR_MANT(x); + xp[xn] = ai << cnt; + /* Zero the xn lower limbs. */ + MPN_ZERO(xp, xn); + MPFR_SET_SIGN (x, i < 0 ? MPFR_SIGN_NEG : MPFR_SIGN_POS); + + nbits = BITS_PER_MP_LIMB - cnt; + e += nbits; /* exponent _before_ the rounding */ + + /* round if MPFR_PREC(x) smaller than length of i */ + if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) && + MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, i < 0, + MPFR_PREC (x), rnd_mode, &inex))) + { + e++; + xp[xn] = MPFR_LIMB_HIGHBIT; + } + + MPFR_CLEAR_FLAGS (x); + MPFR_EXP (x) = e; + return mpfr_check_range (x, inex, rnd_mode); + } } diff -Naurd mpfr-2.2.1-p2/set_ui.c mpfr-2.2.1-p3/set_ui.c --- mpfr-2.2.1-p2/set_ui.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p3/set_ui.c 2007-02-15 23:40:21.000000000 +0000 @@ -19,60 +19,11 @@ the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define MPFR_NEED_LONGLONG_H #include "mpfr-impl.h" #undef mpfr_set_ui int mpfr_set_ui (mpfr_ptr x, unsigned long i, mp_rnd_t rnd_mode) { - int inex; - - MPFR_SET_POS(x); - if (i == 0) - { - MPFR_SET_ZERO(x); - MPFR_RET(0); - } - else - { - mp_size_t xn; - unsigned int cnt, nbits; - mp_limb_t *xp; - - MPFR_CLEAR_FLAGS(x); - - xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB; - MPFR_ASSERTD(i == (mp_limb_t) i); - count_leading_zeros(cnt, (mp_limb_t) i); - - xp = MPFR_MANT(x); - xp[xn] = ((mp_limb_t) i) << cnt; - /* don't forget to put zero in lower limbs */ - MPN_ZERO(xp, xn); - - nbits = BITS_PER_MP_LIMB - cnt; - MPFR_EXP (x) = nbits; /* may be out-of-range, check range below */ - inex = mpfr_check_range(x, 0, rnd_mode); - if (inex) - return inex; /* underflow or overflow */ - - /* round if MPFR_PREC(x) smaller than length of i */ - if (MPFR_UNLIKELY( MPFR_PREC(x) < nbits) ) - { - int carry; - carry = mpfr_round_raw(xp+xn, xp+xn, nbits, 0, MPFR_PREC(x), - rnd_mode, &inex); - if (MPFR_UNLIKELY(carry)) - { - /* nbits is the current exponent */ - if (MPFR_UNLIKELY((mp_exp_t) nbits == __gmpfr_emax)) - return mpfr_overflow(x, rnd_mode, 1); - - MPFR_SET_EXP (x, nbits + 1); - xp[xn] = MPFR_LIMB_HIGHBIT; - } - } - } - MPFR_RET(inex); + return mpfr_set_ui_2exp (x, i, 0, rnd_mode); } diff -Naurd mpfr-2.2.1-p2/set_ui_2exp.c mpfr-2.2.1-p3/set_ui_2exp.c --- mpfr-2.2.1-p2/set_ui_2exp.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p3/set_ui_2exp.c 2007-02-15 23:40:22.000000000 +0000 @@ -20,18 +20,53 @@ the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define MPFR_NEED_LONGLONG_H #include "mpfr-impl.h" int mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mp_exp_t e, mp_rnd_t rnd_mode) { - int res; - MPFR_SAVE_EXPO_DECL (expo); + MPFR_SET_POS (x); - MPFR_SAVE_EXPO_MARK (expo); - res = mpfr_set_ui (x, i, rnd_mode); - mpfr_mul_2si (x, x, e, rnd_mode); /* Should be exact */ - MPFR_SAVE_EXPO_FREE (expo); - res = mpfr_check_range(x, res, rnd_mode); - return res; + if (i == 0) + { + MPFR_SET_ZERO (x); + MPFR_RET (0); + } + else + { + mp_size_t xn; + unsigned int cnt, nbits; + mp_limb_t *xp; + int inex = 0; + + /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */ + MPFR_ASSERTD (i == (mp_limb_t) i); + + /* Position of the highest limb */ + xn = (MPFR_PREC (x) - 1) / BITS_PER_MP_LIMB; + count_leading_zeros (cnt, (mp_limb_t) i); + MPFR_ASSERTD (cnt < BITS_PER_MP_LIMB); /* OK since i != 0 */ + + xp = MPFR_MANT(x); + xp[xn] = ((mp_limb_t) i) << cnt; + /* Zero the xn lower limbs. */ + MPN_ZERO(xp, xn); + + nbits = BITS_PER_MP_LIMB - cnt; + e += nbits; /* exponent _before_ the rounding */ + + /* round if MPFR_PREC(x) smaller than length of i */ + if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) && + MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, 0, + MPFR_PREC (x), rnd_mode, &inex))) + { + e++; + xp[xn] = MPFR_LIMB_HIGHBIT; + } + + MPFR_CLEAR_FLAGS (x); + MPFR_EXP (x) = e; + return mpfr_check_range (x, inex, rnd_mode); + } } diff -Naurd mpfr-2.2.1-p2/tests/tset_si.c mpfr-2.2.1-p3/tests/tset_si.c --- mpfr-2.2.1-p2/tests/tset_si.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p3/tests/tset_si.c 2007-02-15 23:40:21.000000000 +0000 @@ -69,6 +69,27 @@ if (mpfr_cmp_ui (x, 1<<13) || res <= 0) ERROR ("Prec 2 + ui_2exp"); + mpfr_clear_flags (); + mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, GMP_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) + ERROR ("mpfr_set_ui_2exp and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)"); + + mpfr_clear_flags (); + mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, GMP_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) + ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)"); + + mpfr_clear_flags (); + mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, GMP_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_POS (x)) + ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)"); + mpfr_clear (x); } @@ -112,7 +133,8 @@ unsigned long zl, dl; int inex; int r; - mp_exp_t emax; + mp_exp_t emin, emax; + int flag; tests_start_mpfr (); @@ -350,6 +372,43 @@ exit (1); } + emin = mpfr_get_emin (); + mpfr_set_prec (x, 2); + + mpfr_set_emin (4); + mpfr_clear_flags (); + mpfr_set_ui (x, 7, GMP_RNDU); + flag = mpfr_underflow_p (); + mpfr_set_emin (emin); + if (mpfr_cmp_ui (x, 8) != 0) + { + printf ("Error for mpfr_set_ui (x, 7, GMP_RNDU), prec = 2, emin = 4\n"); + exit (1); + } + if (flag) + { + printf ("mpfr_set_ui (x, 7, GMP_RNDU) should not underflow " + "with prec = 2, emin = 4\n"); + exit (1); + } + + mpfr_set_emin (4); + mpfr_clear_flags (); + mpfr_set_si (x, -7, GMP_RNDD); + flag = mpfr_underflow_p (); + mpfr_set_emin (emin); + if (mpfr_cmp_si (x, -8) != 0) + { + printf ("Error for mpfr_set_si (x, -7, GMP_RNDD), prec = 2, emin = 4\n"); + exit (1); + } + if (flag) + { + printf ("mpfr_set_si (x, -7, GMP_RNDD) should not underflow " + "with prec = 2, emin = 4\n"); + exit (1); + } + mpfr_clear (x); test_2exp (); diff -Naurd mpfr-2.2.1-p2/version.c mpfr-2.2.1-p3/version.c --- mpfr-2.2.1-p2/version.c 2007-02-15 23:37:58.000000000 +0000 +++ mpfr-2.2.1-p3/version.c 2007-02-15 23:40:49.000000000 +0000 @@ -24,5 +24,5 @@ const char * mpfr_get_version (void) { - return "2.2.1-p2"; + return "2.2.1-p3"; } diff -Naurd mpfr-2.2.1-p3/VERSION mpfr-2.2.1-p4/VERSION --- mpfr-2.2.1-p3/VERSION 2007-02-15 23:40:49.000000000 +0000 +++ mpfr-2.2.1-p4/VERSION 2007-02-15 23:43:29.000000000 +0000 @@ -1 +1 @@ -2.2.1-p3 +2.2.1-p4 diff -Naurd mpfr-2.2.1-p3/mpfr.h mpfr-2.2.1-p4/mpfr.h --- mpfr-2.2.1-p3/mpfr.h 2007-02-15 23:40:49.000000000 +0000 +++ mpfr-2.2.1-p4/mpfr.h 2007-02-15 23:43:29.000000000 +0000 @@ -26,7 +26,7 @@ #define MPFR_VERSION_MAJOR 2 #define MPFR_VERSION_MINOR 2 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "2.2.1-p3" +#define MPFR_VERSION_STRING "2.2.1-p4" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) diff -Naurd mpfr-2.2.1-p3/pow_si.c mpfr-2.2.1-p4/pow_si.c --- mpfr-2.2.1-p3/pow_si.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p4/pow_si.c 2007-02-15 23:43:17.000000000 +0000 @@ -67,24 +67,20 @@ /* detect exact powers: x^(-n) is exact iff x is a power of 2 */ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0) { - mp_exp_t expx = MPFR_EXP (x); /* warning: x and y may be the same - variable */ - mpfr_set_si (y, (n % 2) ? MPFR_INT_SIGN(x) : 1, rnd); - expx --; + mp_exp_t expx = MPFR_EXP (x) - 1, expy; MPFR_ASSERTD (n < 0); - /* Warning n*expx may overflow! - Some systems abort with LONG_MIN / 1 or LONG_MIN/-1*/ - if (n != -1 && expx > 0 && -expx < MPFR_EXP_MIN / (-n)) - MPFR_EXP (y) = MPFR_EMIN_MIN - 1; /* Underflow */ - else if (n != -1 && expx < 0 && -expx > MPFR_EXP_MAX / (-n)) - MPFR_EXP (y) = MPFR_EMAX_MAX + 1; /* Overflow */ - else - MPFR_EXP (y) += n * expx; - return mpfr_check_range (y, 0, rnd); + /* Warning: n * expx may overflow! + Some systems (apparently alpha-freebsd) abort with + LONG_MIN / 1, and LONG_MIN / -1 is undefined. */ + expy = + n != -1 && expx > 0 && expx > (__gmpfr_emin - 1) / n ? + MPFR_EMIN_MIN - 2 /* Underflow */ : + n != -1 && expx < 0 && expx < (__gmpfr_emax - 1) / n ? + MPFR_EMAX_MAX /* Overflow */ : n * expx; + return mpfr_set_si_2exp (y, n % 2 ? MPFR_INT_SIGN (x) : 1, + expy, rnd); } - n = -n; - /* General case */ { /* Declaration of the intermediary variable */ @@ -94,9 +90,12 @@ mp_prec_t Nt; /* working precision */ mp_exp_t err; /* error */ int inexact; + unsigned long abs_n; MPFR_SAVE_EXPO_DECL (expo); MPFR_ZIV_DECL (loop); + abs_n = - (unsigned long) n; + /* compute the precision of intermediary variable */ /* the optimal number of bits : see algorithms.tex */ Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny); @@ -109,17 +108,17 @@ MPFR_ZIV_INIT (loop, Nt); for (;;) { - /* compute 1/(x^n) n>0*/ - mpfr_pow_ui (t, x, (unsigned long int) n, GMP_RNDN); + /* compute 1/(x^n), with n > 0 */ + mpfr_pow_ui (t, x, abs_n, GMP_RNDN); mpfr_ui_div (t, 1, t, GMP_RNDN); - /* FIXME: old code improved, but I think this is still incorrect. */ + /* FIXME: old code improved, but I think this is still incorrect. */ if (MPFR_UNLIKELY (MPFR_IS_ZERO (t))) { MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); return mpfr_underflow (y, rnd == GMP_RNDN ? GMP_RNDZ : rnd, - (unsigned) n & 1 ? MPFR_SIGN (x) : + abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } if (MPFR_UNLIKELY (MPFR_IS_INF (t))) @@ -127,8 +126,7 @@ MPFR_ZIV_FREE (loop); mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); - return mpfr_overflow (y, rnd, - (unsigned) n & 1 ? MPFR_SIGN (x) : + return mpfr_overflow (y, rnd, abs_n & 1 ? MPFR_SIGN (x) : MPFR_SIGN_POS); } /* error estimate -- see pow function in algorithms.ps */ diff -Naurd mpfr-2.2.1-p3/tests/tpow.c mpfr-2.2.1-p4/tests/tpow.c --- mpfr-2.2.1-p3/tests/tpow.c 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p4/tests/tpow.c 2007-02-15 23:43:17.000000000 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include #include "mpfr-test.h" @@ -231,6 +232,55 @@ mpfr_pow_si (x, x, -2, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + mpfr_set_si (x, 2, GMP_RNDN); + mpfr_pow_si (x, x, LONG_MAX, GMP_RNDN); /* 2^LONG_MAX */ + if (LONG_MAX > mpfr_get_emax () - 1) /* LONG_MAX + 1 > emax */ + { + MPFR_ASSERTN (mpfr_inf_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MAX)); + } + + mpfr_set_si (x, 2, GMP_RNDN); + mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 2^LONG_MIN */ + if (LONG_MIN + 1 < mpfr_get_emin ()) + { + MPFR_ASSERTN (mpfr_zero_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN)); + } + + mpfr_set_si (x, 2, GMP_RNDN); + mpfr_pow_si (x, x, LONG_MIN + 1, GMP_RNDN); /* 2^(LONG_MIN+1) */ + if (mpfr_nan_p (x)) + { + printf ("Error in pow_si(2, LONG_MIN+1): got NaN\n"); + exit (1); + } + if (LONG_MIN + 2 < mpfr_get_emin ()) + { + MPFR_ASSERTN (mpfr_zero_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, LONG_MIN + 1)); + } + + mpfr_set_si_2exp (x, 1, -1, GMP_RNDN); /* 0.5 */ + mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 2^(-LONG_MIN) */ + if (LONG_MIN < 1 - mpfr_get_emax ()) /* 1 - LONG_MIN > emax */ + { + MPFR_ASSERTN (mpfr_inf_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 2, - (LONG_MIN + 1))); + } + mpfr_clear (x); } @@ -270,6 +320,35 @@ } static void +pow_si_long_min (void) +{ + mpfr_t x, y, z; + int inex; + + mpfr_inits2 (sizeof(long) * CHAR_BIT + 32, x, y, z, (void *) 0); + mpfr_set_si_2exp (x, 3, -1, GMP_RNDN); /* 1.5 */ + + inex = mpfr_set_si (y, LONG_MIN, GMP_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_nextbelow (y); + mpfr_pow (y, x, y, GMP_RNDD); + + inex = mpfr_set_si (z, LONG_MIN, GMP_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_nextabove (z); + mpfr_pow (z, x, z, GMP_RNDU); + + mpfr_pow_si (x, x, LONG_MIN, GMP_RNDN); /* 1.5^LONG_MIN */ + if (mpfr_cmp (x, y) < 0 || mpfr_cmp (x, z) > 0) + { + printf ("Error in pow_si_long_min\n"); + exit (1); + } + + mpfr_clears (x, y, z, (void *) 0); +} + +static void check_inexact (mp_prec_t p) { mpfr_t x, y, z, t; @@ -751,6 +830,7 @@ check_pow_ui (); check_pow_si (); check_special_pow_si (); + pow_si_long_min (); for (p = 2; p < 100; p++) check_inexact (p); underflows (); diff -Naurd mpfr-2.2.1-p3/version.c mpfr-2.2.1-p4/version.c --- mpfr-2.2.1-p3/version.c 2007-02-15 23:40:49.000000000 +0000 +++ mpfr-2.2.1-p4/version.c 2007-02-15 23:43:29.000000000 +0000 @@ -24,5 +24,5 @@ const char * mpfr_get_version (void) { - return "2.2.1-p3"; + return "2.2.1-p4"; } diff -Naurd mpfr-2.2.1-p4/VERSION mpfr-2.2.1-p5/VERSION --- mpfr-2.2.1-p4/VERSION 2007-02-15 23:43:29.000000000 +0000 +++ mpfr-2.2.1-p5/VERSION 2007-02-15 23:46:49.000000000 +0000 @@ -1 +1 @@ -2.2.1-p4 +2.2.1-p5 diff -Naurd mpfr-2.2.1-p4/mpfr.h mpfr-2.2.1-p5/mpfr.h --- mpfr-2.2.1-p4/mpfr.h 2007-02-15 23:43:29.000000000 +0000 +++ mpfr-2.2.1-p5/mpfr.h 2007-02-15 23:46:49.000000000 +0000 @@ -26,7 +26,7 @@ #define MPFR_VERSION_MAJOR 2 #define MPFR_VERSION_MINOR 2 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "2.2.1-p4" +#define MPFR_VERSION_STRING "2.2.1-p5" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) diff -Naurd mpfr-2.2.1-p4/mpfr.info mpfr-2.2.1-p5/mpfr.info --- mpfr-2.2.1-p4/mpfr.info 2006-11-29 09:51:26.000000000 +0000 +++ mpfr-2.2.1-p5/mpfr.info 2007-02-15 23:46:21.000000000 +0000 @@ -1,10 +1,10 @@ This is mpfr.info, produced by makeinfo version 4.8 from mpfr.texi. This manual documents how to install and use the Multiple Precision -Floating-Point Reliable Library, version 2.2.1. +Floating-Point Reliable Library, version 2.2.2-p5. Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version @@ -26,10 +26,10 @@ **** This manual documents how to install and use the Multiple Precision -Floating-Point Reliable Library, version 2.2.1. +Floating-Point Reliable Library, version 2.2.2-p5. Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version @@ -173,7 +173,7 @@ This will copy the files `mpfr.h' and `mpf2mpfr.h' to the directory `/usr/local/include', the file `libmpfr.a' to the directory `/usr/local/lib', and the file `mpfr.info' to the directory - `/usr/local/info' (or if you passed the `--prefix' option to + `/usr/local/share/info' (or if you passed the `--prefix' option to `configure', using the prefix directory given as argument to `--prefix' instead of `/usr/local'). @@ -396,6 +396,53 @@ should return an overflow or an underflow if `1' is not representable in the current exponent range. +4.5 Exceptions +============== + +MPFR supports 5 exception types: + + * Underflow: An underflow occurs when the exact result of a function + is a non-zero real number and the result obtained after the + rounding, assuming an unbounded exponent range (for the rounding), + has an exponent smaller than the minimum exponent of the current + range. In the round-to-nearest mode, the halfway case is rounded + toward zero. + + Note: This is not the single definition of the underflow. MPFR + chooses to consider the underflow after rounding. The underflow + before rounding can also be defined. For instance, consider a + function that has the exact result 7 multiplied by two to the power + E-4, where E is the smallest exponent (for a mantissa between 1/2 + and 1) in the current range, with a 2-bit target precision and + rounding towards plus infinity. The exact result has the exponent + E-1. With the underflow before rounding, such a function call + would yield an underflow, as E-1 is outside the current exponent + range. However, MPFR first considers the rounded result assuming + an unbounded exponent range. The exact result cannot be + represented exactly in precision 2, and here, it is rounded to 0.5 + times 2 to E, which is representable in the current exponent + range. As a consequence, this will not yield an underflow in MPFR. + + * Overflow: An overflow occurs when the exact result of a function + is a non-zero real number and the result obtained after the + rounding, assuming an unbounded exponent range (for the rounding), + has an exponent larger than the maximum exponent of the current + range. In the round-to-nearest mode, the result is infinite. + + * Invalid (NaN): An invalid (or NaN) exception occurs when the + result of a function is a NaN. + + * Inexact: An inexact exception occurs when the result of a function + cannot be represented exactly and must be rounded. + + * Range error: A range exception occurs when a function that does + not return a MPFR number (such as comparisons and conversions to + an integer) has an invalid result. + + + MPFR has a global flag for each exception, which can be cleared, set +or tested by functions described in *Note Exceptions::. +  File: mpfr.info, Node: MPFR Interface, Next: Contributors, Prev: MPFR Basics, Up: Top @@ -950,6 +997,12 @@ Set ROP to the absolute value of OP, rounded in the direction RND. Just changes the sign if ROP and OP are the same variable. + -- Function: int mpfr_dim (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2, + mp_rnd_t RND) + Set ROP to the positive difference of OP1 and OP2, i.e., OP1 - OP2 + rounded in the direction RND if OP1 > OP2, and +0 otherwise. + Returns NaN when OP1 or OP2 is NaN. + -- Function: int mpfr_mul_2ui (mpfr_t ROP, mpfr_t OP1, unsigned long int OP2, mp_rnd_t RND) -- Function: int mpfr_mul_2si (mpfr_t ROP, mpfr_t OP1, long int OP2, @@ -1873,9 +1926,12 @@ Meunier helped in the design of the `mpfr_erf' code. The development of the MPFR library would not have been possible -without the continuous support of LORIA, INRIA and INRIA Lorraine. The -development of MPFR was also supported by a grant (202F0659 00 MPN 121) -from the Conseil Régional de Lorraine in 2002. +without the continuous support of INRIA, and of the LORIA and LIP +laboratories. In particular the main authors were or are members of the +PolKA, Spaces, Cacao project-teams at LORIA (Nancy, France) and of the +Arenaire project-team at LIP (Lyon, France). The development of MPFR +was also supported by a grant (202F0659 00 MPN 121) from the Conseil +Régional de Lorraine in 2002.  File: mpfr.info, Node: References, Next: GNU Free Documentation License, Prev: Contributors, Up: Top @@ -2387,8 +2443,8 @@ * Precision <1>: MPFR Interface. (line 20) * Precision: MPFR Basics. (line 26) * Reporting bugs: Reporting Bugs. (line 6) -* Rounding Modes <1>: Rounding Modes. (line 6) -* Rounding Modes: MPFR Basics. (line 32) +* Rounding Modes <1>: MPFR Basics. (line 32) +* Rounding Modes: Rounding Modes. (line 6) * Special functions: Special Functions. (line 6)  @@ -2477,14 +2533,16 @@ * mpfr_custom_init_set: Custom Interface. (line 47) * mpfr_custom_move: Custom Interface. (line 84) * MPFR_DECL_INIT: Advanced Functions. (line 10) +* mpfr_dim: Basic Arithmetic Functions. + (line 155) * mpfr_div: Basic Arithmetic Functions. (line 58) * mpfr_div_2exp: Compatibility with MPF. (line 47) * mpfr_div_2si: Basic Arithmetic Functions. - (line 164) + (line 170) * mpfr_div_2ui: Basic Arithmetic Functions. - (line 162) + (line 168) * mpfr_div_q: Basic Arithmetic Functions. (line 70) * mpfr_div_si: Basic Arithmetic Functions. @@ -2625,9 +2683,9 @@ * mpfr_mul_2exp: Compatibility with MPF. (line 45) * mpfr_mul_2si: Basic Arithmetic Functions. - (line 157) + (line 163) * mpfr_mul_2ui: Basic Arithmetic Functions. - (line 155) + (line 161) * mpfr_mul_q: Basic Arithmetic Functions. (line 48) * mpfr_mul_si: Basic Arithmetic Functions. @@ -2808,33 +2866,33 @@  Tag Table: -Node: Top949 -Node: Copying2260 -Node: Introduction to MPFR3977 -Node: Installing MPFR5675 -Node: Reporting Bugs8343 -Node: MPFR Basics9895 -Node: MPFR Interface16074 -Node: Initialization Functions18238 -Node: Assignment Functions21660 -Node: Combined Initialization and Assignment Functions28550 -Node: Conversion Functions29832 -Node: Basic Arithmetic Functions35481 -Node: Comparison Functions42745 -Node: Special Functions46215 -Node: Input and Output Functions55364 -Node: Integer Related Functions57300 -Node: Miscellaneous Functions60294 -Node: Rounding Modes64675 -Node: Exceptions66024 -Node: Advanced Functions71338 -Node: Compatibility with MPF73943 -Node: Custom Interface76212 -Node: Internals80255 -Node: Contributors82275 -Node: References84024 -Node: GNU Free Documentation License84769 -Node: Concept Index107212 -Node: Function Index111074 +Node: Top958 +Node: Copying2278 +Node: Introduction to MPFR3995 +Node: Installing MPFR5693 +Node: Reporting Bugs8367 +Node: MPFR Basics9919 +Node: MPFR Interface18384 +Node: Initialization Functions20548 +Node: Assignment Functions23970 +Node: Combined Initialization and Assignment Functions30860 +Node: Conversion Functions32142 +Node: Basic Arithmetic Functions37791 +Node: Comparison Functions45323 +Node: Special Functions48793 +Node: Input and Output Functions57942 +Node: Integer Related Functions59878 +Node: Miscellaneous Functions62872 +Node: Rounding Modes67253 +Node: Exceptions68602 +Node: Advanced Functions73916 +Node: Compatibility with MPF76521 +Node: Custom Interface78790 +Node: Internals82833 +Node: Contributors84853 +Node: References86790 +Node: GNU Free Documentation License87535 +Node: Concept Index109978 +Node: Function Index113840  End Tag Table diff -Naurd mpfr-2.2.1-p4/mpfr.texi mpfr-2.2.1-p5/mpfr.texi --- mpfr-2.2.1-p4/mpfr.texi 2006-11-29 09:49:47.000000000 +0000 +++ mpfr-2.2.1-p5/mpfr.texi 2007-02-15 23:46:09.000000000 +0000 @@ -2,8 +2,8 @@ @c %**start of header @setfilename mpfr.info @documentencoding ISO-8859-1 -@set VERSION 2.2.1 -@set UPDATED-MONTH November 2006 +@set VERSION 2.2.2-p5 +@set UPDATED-MONTH February 2007 @settitle MPFR @value{VERSION} @synindex tp fn @iftex @@ -15,7 +15,7 @@ This manual documents how to install and use the Multiple Precision Floating-Point Reliable Library, version @value{VERSION}. -Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later @@ -312,7 +312,7 @@ This will copy the files @file{mpfr.h} and @file{mpf2mpfr.h} to the directory @file{/usr/local/include}, the file @file{libmpfr.a} to the directory @file{/usr/local/lib}, and the file @file{mpfr.info} to the directory -@file{/usr/local/info} (or if you passed the @samp{--prefix} option to +@file{/usr/local/share/info} (or if you passed the @samp{--prefix} option to @file{configure}, using the prefix directory given as argument to @samp{--prefix} instead of @file{/usr/local}). @end enumerate @@ -559,6 +559,61 @@ for special cases (like @code{acos(0)}) should return an overflow or an underflow if @code{1} is not representable in the current exponent range. +@section Exceptions + +MPFR supports 5 exception types: + +@itemize @bullet + +@item Underflow: +An underflow occurs when the exact result of a function is a non-zero +real number and the result obtained after the rounding, assuming an +unbounded exponent range (for the rounding), has an exponent smaller +than the minimum exponent of the current range. In the round-to-nearest +mode, the halfway case is rounded toward zero. + +Note: This is not the single definition of the underflow. MPFR chooses +to consider the underflow after rounding. The underflow before rounding +can also be defined. For instance, consider a function that has the +exact result @m{7 \times 2^{e-4}, 7 multiplied by two to the power +@var{e}@minus{}4}, where @var{e} is the smallest exponent (for a +mantissa between 1/2 and 1) in the current +range, with a 2-bit target precision and rounding towards plus infinity. +The exact result has the exponent @var{e}@minus{}1. With the underflow +before rounding, such a function call would yield an underflow, as +@var{e}@minus{}1 is outside the current exponent range. However, MPFR +first considers the rounded result assuming an unbounded exponent range. +The exact result cannot be represented exactly in precision 2, and here, +it is rounded to @m{0.5 @times 2^e, 0.5 times 2 to @var{e}}, which is +representable in the current exponent range. As a consequence, this will +not yield an underflow in MPFR. + +@item Overflow: +An overflow occurs when the exact result of a function is a non-zero +real number and the result obtained after the rounding, assuming an +unbounded exponent range (for the rounding), has an exponent larger +than the maximum exponent of the current range. In the round-to-nearest +mode, the result is infinite. + +@item Invalid (NaN): +An invalid (or NaN) exception occurs when the result of a function is +a NaN. +@c NaN is defined above. So, we don't say anything more. + +@item Inexact: +An inexact exception occurs when the result of a function cannot be +represented exactly and must be rounded. + +@item Range error: +A range exception occurs when a function that does not return a MPFR +number (such as comparisons and conversions to an integer) has an +invalid result. + +@end itemize + +MPFR has a global flag for each exception, which can be cleared, set +or tested by functions described in @ref{Exceptions}. + @node MPFR Interface, Contributors, MPFR Basics, Top @comment node-name, next, previous, up @chapter MPFR Interface @@ -1130,6 +1185,13 @@ Just changes the sign if @var{rop} and @var{op} are the same variable. @end deftypefun +@deftypefun int mpfr_dim (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd}) +Set @var{rop} to the positive difference of @var{op1} and @var{op2}, i.e., +@math{@var{op1} - @var{op2}} rounded in the direction @var{rnd} +if @math{@var{op1} > @var{op2}}, and +0 otherwise. +Returns NaN when @var{op1} or @var{op2} is NaN. +@end deftypefun + @deftypefun int mpfr_mul_2ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd}) @deftypefunx int mpfr_mul_2si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mp_rnd_t @var{rnd}) Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised @@ -2196,7 +2258,10 @@ Ludovic Meunier helped in the design of the @code{mpfr_erf} code. The development of the MPFR library would not have been possible without the -continuous support of LORIA, INRIA and INRIA Lorraine. +continuous support of INRIA, and of the LORIA and LIP laboratories. +In particular the main authors were or are members of the +PolKA, Spaces, Cacao project-teams at LORIA (Nancy, France) +and of the Arenaire project-team at LIP (Lyon, France). The development of MPFR was also supported by a grant (202F0659 00 MPN 121) from the Conseil R@'egional de Lorraine in 2002. diff -Naurd mpfr-2.2.1-p4/version.c mpfr-2.2.1-p5/version.c --- mpfr-2.2.1-p4/version.c 2007-02-15 23:43:29.000000000 +0000 +++ mpfr-2.2.1-p5/version.c 2007-02-15 23:46:49.000000000 +0000 @@ -24,5 +24,5 @@ const char * mpfr_get_version (void) { - return "2.2.1-p4"; + return "2.2.1-p5"; }