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"; }