diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-12-19 16:11:17 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-12-19 16:11:17 +0000 |
commit | aec3cddaccff9e146f7ecb2777aff927a1db0980 (patch) | |
tree | e07d4e05050b3786188bfbaa3b1f1ffbdd9b5fbc | |
parent | 3b45fa5f7a1d47b485a09003509f3b500eaa0b0c (diff) | |
download | mpfr-aec3cddaccff9e146f7ecb2777aff927a1db0980.tar.gz |
[src/strtofr.c] Fixed bug in mpfr_strtofr(): in round-to-nearest,
the ternary value could be incorrect.
[tests/tstrtofr.c] Added test case.
(merged changesets from the trunk: r11055, a part of r11056, and
r11059,11066-11068)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/3.1@11069 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/strtofr.c | 13 | ||||
-rw-r--r-- | tests/tstrtofr.c | 19 |
2 files changed, 27 insertions, 5 deletions
diff --git a/src/strtofr.c b/src/strtofr.c index 67f5caa62..a1904cc04 100644 --- a/src/strtofr.c +++ b/src/strtofr.c @@ -743,11 +743,14 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd) of the pstr_size most significant digits of pstr->mant, with equality in case exact is non-zero. */ - /* test if rounding is possible, and if so exit the loop */ - if (exact || mpfr_can_round_raw (result, ysize, - (pstr->negative) ? -1 : 1, - ysize_bits - err - 1, - MPFR_RNDN, rnd, MPFR_PREC(x))) + /* test if rounding is possible, and if so exit the loop. + Note: we also need to be able to determine the correct ternary value, + thus we use the MPFR_PREC(x) + (rnd == MPFR_RNDN) trick. + For example if result = xxx...xxx111...111 and rnd = RNDN, + then we know the correct rounding is xxx...xx(x+1), but we cannot know + the correct ternary value. */ + if (exact || mpfr_round_p (result, ysize, ysize_bits - err - 1, + MPFR_PREC(x) + (rnd == MPFR_RNDN))) break; next_loop: diff --git a/tests/tstrtofr.c b/tests/tstrtofr.c index 97575413a..46b76c625 100644 --- a/tests/tstrtofr.c +++ b/tests/tstrtofr.c @@ -1191,6 +1191,24 @@ bug20120829 (void) mpfr_clears (e, x1, x2, (mpfr_ptr) 0); } +/* Note: the number is 5^47/2^9. */ +static void +bug20161217 (void) +{ + mpfr_t fp, z; + static const char * num = "0.1387778780781445675529539585113525390625e31"; + int inex; + + mpfr_init2 (fp, 110); + mpfr_init2 (z, 110); + inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN); + MPFR_ASSERTN(inex == 0); + mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001101E-9"); + MPFR_ASSERTN(mpfr_equal_p (fp, z)); + mpfr_clear (fp); + mpfr_clear (z); +} + int main (int argc, char *argv[]) { @@ -1205,6 +1223,7 @@ main (int argc, char *argv[]) test20100310 (); bug20120814 (); bug20120829 (); + bug20161217 (); tests_end_mpfr (); return 0; |