diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-03 12:03:05 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-03 12:03:05 +0000 |
commit | a997ac05cfe765ba7d32dec53b41b0e9a3d94705 (patch) | |
tree | 51263880cbffa27920652ad8fd1c191910fcddb7 /src | |
parent | a7aa914c3526d87d7327f21f337f69d8b8c7822e (diff) | |
download | mpfr-a997ac05cfe765ba7d32dec53b41b0e9a3d94705.tar.gz |
[src/rint.c] Handle reduced exponent range.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9489 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src')
-rw-r--r-- | src/rint.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/src/rint.c b/src/rint.c index 867e4df59..ed0494ff5 100644 --- a/src/rint.c +++ b/src/rint.c @@ -24,7 +24,14 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., /* Merge the following mpfr_rint code with mpfr_round_raw_generic? */ -/* FIXME: handle reduced exponent range (and add regression tests). */ +/* For all the round-to-integer functions, we don't need to extend the + * exponent range. And it is better not to do so, so that we can test + * the flag setting for intermediate overflow in the test suite without + * involving huge non-integer numbers (thus in huge precision). This + * should also be faster. + * + * We also need to be careful with the flags. + */ int mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) @@ -79,14 +86,9 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) (exp == 0 && (rnd_mode == MPFR_RNDNA || !mpfr_powerof2_raw (u))))) { - mp_limb_t *rp; - mp_size_t rm; - - rp = MPFR_MANT(r); - rm = (MPFR_PREC(r) - 1) / GMP_NUMB_BITS; - rp[rm] = MPFR_LIMB_HIGHBIT; - MPN_ZERO(rp, rm); - MPFR_SET_EXP (r, 1); /* |r| = 1 */ + /* The flags will correctly be set and overflow will correctly + be handled by mpfr_set_si. */ + mpfr_set_si (r, sign, rnd_mode); MPFR_RET(sign > 0 ? 2 : -2); } else @@ -116,6 +118,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) rn = MPFR_LIMB_SIZE(r); MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (r)); + /* exp is in the current exponent range: obtained from the input. */ MPFR_SET_EXP (r, exp); /* Does nothing if r==u */ if ((exp - 1) / GMP_NUMB_BITS >= un) @@ -288,9 +291,9 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) if (rnd_away && mpn_add_1(rp, rp, rn, MPFR_LIMB_ONE << sh)) { if (exp == __gmpfr_emax) - return mpfr_overflow(r, rnd_mode, MPFR_SIGN(r)) >= 0 ? + return mpfr_overflow (r, rnd_mode, sign) >= 0 ? uflags : -uflags; - else + else /* no overflow */ { MPFR_SET_EXP(r, exp + 1); rp[rn-1] = MPFR_LIMB_HIGHBIT; @@ -333,15 +336,9 @@ mpfr_floor (mpfr_ptr r, mpfr_srcptr u) return mpfr_rint (r, u, MPFR_RNDD); } -/* For the round-to-integer functions below, we don't need to extend the - * exponent range. And it is better not to do so, so that we can test - * the flag setting for intermediate overflow in the test suite without - * involving huge non-integer numbers (thus in huge precision). This - * should also be faster. - * - * Moreover we need to save the flags and restore them after calling the - * mpfr_round, mpfr_trunc, mpfr_ceil, mpfr_floor functions because these - * functions set the inexact flag when the argument is not an integer. +/* We need to save the flags and restore them after calling the mpfr_round, + * mpfr_trunc, mpfr_ceil, mpfr_floor functions because these functions set + * the inexact flag when the argument is not an integer. */ #undef mpfr_rint_round |