diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-06-06 15:57:16 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-06-06 15:57:16 +0000 |
commit | 6d78aa901077777cfa346e1b52de79f74241c2bb (patch) | |
tree | bcbb91338e5b9df78135a52645f04aadd9e8c0d6 | |
parent | 737c59ef6906e8eb2ce6b5dda90aa51e9cbab4ad (diff) | |
parent | c4d3cdb70230a418460101fd925a971f8e7192a0 (diff) | |
download | mpfr-6d78aa901077777cfa346e1b52de79f74241c2bb.tar.gz |
Merged the latest changes from the trunk.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/ubf@10439 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | TODO | 18 | ||||
-rw-r--r-- | src/add1.c | 6 | ||||
-rw-r--r-- | src/fits_intmax.c | 2 | ||||
-rw-r--r-- | src/fits_s.h | 2 | ||||
-rw-r--r-- | src/set_float128.c | 13 | ||||
-rw-r--r-- | tests/tset_float128.c | 37 |
6 files changed, 60 insertions, 18 deletions
@@ -451,6 +451,24 @@ Table of contents: * In debug mode, MPFR would check that the result is exact (i.e. that the ternary value is 0). +- new "rounding mode" MPFR_RNDF (faithful rounding)? + This is not really a rounding mode since it is non-deterministic. The + goal is to avoid the Table Maker's Dilemma in internal computations. + The definition of faithful rounding of a real number x is: return either + RNDD(x) or RNDU(x). This means that if x is exactly representable, one + returns x exactly. In MPFR, the ternary value should be unspecified for + efficiency reasons. + Note: One typically implements faithful rounding by computing an + approximation to the result with some adequately chosen error bound, + then by rounding this approximation to nearest. + Concerning the choice of the error bound, if the result x is equal to + 1 + t, where t is a very small positive number, then the error bound + needs to be at most ulp(x)/4 + t. Since t can be arbitrarily small, + the error bound needs to be at most ulp(x)/4. And this error bound + is sufficient in all cases. Note that with the even rounding rule or + rounding away from zero, it is not needed to relax the condition when + x is exactly representable. + - add tests of the ternary value for constants - When doing Extensive Check (--enable-assert=full), since all the diff --git a/src/add1.c b/src/add1.c index 37284a9b1..4e210390e 100644 --- a/src/add1.c +++ b/src/add1.c @@ -248,11 +248,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) if (fb > 0) { if (bb != MPFR_LIMB_MAX) - { - fb = 1; /* c hasn't been taken into account - ==> sticky bit != 0 */ - goto rounding; - } + goto rounding; } else /* fb not initialized yet */ { diff --git a/src/fits_intmax.c b/src/fits_intmax.c index 423ed1b14..0f738c2f7 100644 --- a/src/fits_intmax.c +++ b/src/fits_intmax.c @@ -41,7 +41,7 @@ mpfr_fits_intmax_p (mpfr_srcptr f, mpfr_rnd_t rnd) int res; if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) - /* Zero always fit */ + /* Zero always fits */ return MPFR_IS_ZERO (f) ? 1 : 0; /* now it fits if either diff --git a/src/fits_s.h b/src/fits_s.h index c639fbb12..93f970b2a 100644 --- a/src/fits_s.h +++ b/src/fits_s.h @@ -37,7 +37,7 @@ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd) int res; if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) - /* Zero always fit */ + /* Zero always fits */ return MPFR_IS_ZERO (f) ? 1 : 0; /* now it fits if either diff --git a/src/set_float128.c b/src/set_float128.c index 98e47449b..8aa11bd43 100644 --- a/src/set_float128.c +++ b/src/set_float128.c @@ -28,6 +28,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #ifdef MPFR_WANT_FLOAT128 +/* The q suffix is a GNU C extension, but so is __float128. */ +#define MPFR_FLOAT128_MAX 0x1.ffffffffffffffffffffffffffffp+16383q + int mpfr_set_float128 (mpfr_ptr r, __float128 d, mpfr_rnd_t rnd_mode) { @@ -44,14 +47,16 @@ mpfr_set_float128 (mpfr_ptr r, __float128 d, mpfr_rnd_t rnd_mode) } /* Check for INF */ - if (MPFR_UNLIKELY (d == ((__float128) 1.0 / (__float128) 0.0))) + if (MPFR_UNLIKELY (d > MPFR_FLOAT128_MAX)) { - mpfr_set_inf (r, 1); + MPFR_SET_INF (r); + MPFR_SET_POS (r); return 0; } - else if (MPFR_UNLIKELY (d == ((__float128) -1.0 / (__float128) 0.0))) + else if (MPFR_UNLIKELY (d < -MPFR_FLOAT128_MAX)) { - mpfr_set_inf (r, -1); + MPFR_SET_INF (r); + MPFR_SET_NEG (r); return 0; } /* Check for ZERO */ diff --git a/tests/tset_float128.c b/tests/tset_float128.c index ad50bf820..a325ceecc 100644 --- a/tests/tset_float128.c +++ b/tests/tset_float128.c @@ -40,10 +40,11 @@ check_special (void) mpfr_init2 (x, 113); +#if !defined(MPFR_ERRDIVZERO) /* check NaN */ f = 0.0 / 0.0; mpfr_set_float128 (x, f, MPFR_RNDN); - if (mpfr_nan_p (x) == 0) + if (! mpfr_nan_p (x)) { printf ("Error in mpfr_set_float128(x, NaN)\n"); exit (1); @@ -59,7 +60,7 @@ check_special (void) /* check +Inf */ f = 1.0 / 0.0; mpfr_set_float128 (x, f, MPFR_RNDN); - if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) < 0) + if (! mpfr_inf_p (x) || MPFR_IS_NEG (x)) { printf ("Error in mpfr_set_float128(x, +Inf)\n"); exit (1); @@ -74,7 +75,7 @@ check_special (void) /* check -Inf */ f = -1.0 / 0.0; mpfr_set_float128 (x, f, MPFR_RNDN); - if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) > 0) + if (! mpfr_inf_p (x) || MPFR_IS_POS (x)) { printf ("Error in mpfr_set_float128(x, -Inf)\n"); exit (1); @@ -85,36 +86,58 @@ check_special (void) printf ("Error in mpfr_get_float128(-Inf)\n"); exit (1); } +#endif /* check +0 */ f = 0.0; mpfr_set_float128 (x, f, MPFR_RNDN); - if (mpfr_zero_p (x) == 0 || mpfr_sgn (x) < 0) + if (! mpfr_zero_p (x) || MPFR_IS_NEG (x)) { printf ("Error in mpfr_set_float128(x, +0)\n"); exit (1); } f = mpfr_get_float128 (x, MPFR_RNDN); - if (f != 0.0 || 1 / f != 1 / 0.0) + if (f != 0.0) /* the sign is not checked */ + { + printf ("Error in mpfr_get_float128(+0.0)\n"); + exit (1); + } +#if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ) + if (1 / f != 1 / 0.0) /* check the sign */ { printf ("Error in mpfr_get_float128(+0.0)\n"); exit (1); } +#endif /* check -0 */ f = -0.0; mpfr_set_float128 (x, f, MPFR_RNDN); - if (mpfr_zero_p (x) == 0 || mpfr_sgn (x) > 0) + if (! mpfr_zero_p (x)) + { + printf ("Error in mpfr_set_float128(x, -0)\n"); + exit (1); + } +#if defined(HAVE_SIGNEDZ) + if (MPFR_IS_POS (x)) { printf ("Error in mpfr_set_float128(x, -0)\n"); exit (1); } +#endif f = mpfr_get_float128 (x, MPFR_RNDN); - if (f != -0.0 || 1 / f != 1 / -0.0) + if (f != -0.0) /* the sign is not checked */ + { + printf ("Error in mpfr_get_float128(-0.0)\n"); + exit (1); + } +#if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ) + if (1 / f != 1 / -0.0) /* check the sign */ { printf ("Error in mpfr_get_float128(-0.0)\n"); exit (1); } +#endif mpfr_clear (x); } |