diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2013-09-26 10:47:05 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2013-09-26 10:47:05 +0000 |
commit | d4aa7f855bd5ddc690797b5c8067dfbe4bded673 (patch) | |
tree | f15fe1dc2f5ee61c31f458fd22e1d3101676b657 /src/fits_u.h | |
parent | 2856faa64801ec5c1a32f828ee2fa8652e60dcc2 (diff) | |
download | mpfr-d4aa7f855bd5ddc690797b5c8067dfbe4bded673.tar.gz |
[src/{fits_u.h,fits_uintmax.c}] Fixed the mpfr_fits_u*_p functions,
which incorrectly returned 0 ("doesn't fit") on negative arguments
when the rounding to an integer was 0. The fits_uintmax.c file now
uses fits_u.h for consistency.
[tests/tfits.c] Added tests, in particular for small negative op
(triggering the above bug) and in non-RNDN rounding modes.
(merged changesets r8494,8501-8503 from the trunk)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/3.1@8684 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/fits_u.h')
-rw-r--r-- | src/fits_u.h | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/fits_u.h b/src/fits_u.h index e4bd6a024..fe4de05c1 100644 --- a/src/fits_u.h +++ b/src/fits_u.h @@ -32,17 +32,20 @@ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd) int res; if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) - /* Zero always fit */ - return MPFR_IS_ZERO (f) ? 1 : 0; - else if (MPFR_IS_NEG (f)) - /* Negative numbers don't fit */ - return 0; - /* now it fits if - (a) f <= MAXIMUM - (b) round(f, prec(slong), rnd) <= MAXIMUM */ + return MPFR_IS_ZERO (f) ? 1 : 0; /* Zero always fits */ e = MPFR_GET_EXP (f); + if (MPFR_IS_NEG (f)) + return e >= 1 ? 0 /* f <= -1 does not fit */ + : rnd != MPFR_RNDN ? MPFR_IS_LIKE_RNDU (rnd, -1) /* directed mode */ + : e < 0 ? 1 /* f > -1/2 fits in MPFR_RNDN */ + : mpfr_powerof2_raw(f); /* -1/2 fits, -1 < f < -1/2 don't */ + + /* Now it fits if + (a) f <= MAXIMUM + (b) round(f, prec(slong), rnd) <= MAXIMUM */ + /* first compute prec(MAXIMUM); fits in an int */ for (s = MAXIMUM, prec = 0; s != 0; s /= 2, prec ++); |