diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2008-10-29 14:29:45 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2008-10-29 14:29:45 +0000 |
commit | 620e7056072a2557366cb06a8f2603fa2642f927 (patch) | |
tree | 300aa718c70e52101c4a5be010e804bbf6dd8d8f | |
parent | 20bfb20c6799e39ad989c894fb5b3e6570170cbc (diff) | |
download | mpfr-620e7056072a2557366cb06a8f2603fa2642f927.tar.gz |
Fixed bug 6604 "incorrect directed rounding in mpfr_strtofr"
in strtofr.c (to be checked) and added testcases. Other minor
corrections. [merged -r5655:5658 -r5659:5662 from trunk]
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/2.3@5664 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | strtofr.c | 15 | ||||
-rw-r--r-- | tests/tset_str.c | 19 | ||||
-rw-r--r-- | tests/tstrtofr.c | 71 |
3 files changed, 79 insertions, 26 deletions
@@ -473,7 +473,7 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mp_rnd_t rnd) if (pstr_size >= pstr->prec) pstr_size = pstr->prec; - MPFR_ASSERTD ((mp_exp_t) pstr_size == (mp_exp_t) pstr_size); + MPFR_ASSERTD (pstr_size == (mp_exp_t) pstr_size); /* convert str into binary */ real_ysize = mpn_set_str (y, pstr->mant, pstr_size, pstr->base); @@ -656,6 +656,19 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mp_rnd_t rnd) err = 0; } + if (pstr_size < pstr->prec && exact + && ((rnd == GMP_RNDN) + || ((rnd == GMP_RNDD && pstr->negative) + || (rnd == GMP_RNDU && !pstr->negative)))) + { + /* Some significant digits might have been forgotten, if so result + is not exact. */ + size_t i; + + for (i = pstr_size; exact && i < pstr->prec; i++) + exact = pstr->mant[i] == 0; + } + /* test if rounding is possible, and if so exit the loop */ if (exact || mpfr_can_round_raw (result, ysize, (pstr->negative) ? -1 : 1, diff --git a/tests/tset_str.c b/tests/tset_str.c index e0e0f80ea..c83e4f54e 100644 --- a/tests/tset_str.c +++ b/tests/tset_str.c @@ -81,6 +81,24 @@ check_underflow (void) mpfr_clear (a); } +/* Bug found by Christoph Lauter. */ +static void +bug20081028 (void) +{ + mpfr_t x; + const char *s = "0.10000000000000000000000000000001E1"; + + mpfr_init2 (x, 32); + mpfr_set_str (x, "1.00000000000000000006", 10, GMP_RNDU); + if (! mpfr_greater_p (x, __gmpfr_one)) + { + printf ("Error in bug20081028:\nExpected %s\nGot ", s); + mpfr_dump (x); + exit (1); + } + mpfr_clear (x); +} + int main (int argc, char *argv[]) { @@ -845,6 +863,7 @@ main (int argc, char *argv[]) mpfr_clear (y); check_underflow (); + bug20081028 (); tests_end_mpfr (); return 0; diff --git a/tests/tstrtofr.c b/tests/tstrtofr.c index 3a0862809..2243bef7e 100644 --- a/tests/tstrtofr.c +++ b/tests/tstrtofr.c @@ -27,28 +27,7 @@ MA 02110-1301, USA. */ #include "mpfr-test.h" -static void check_reftable (void); -static void check_special (void); -static void check_retval (void); -static void check_overflow (void); -static void check_parse (void); - -int -main (int argc, char *argv[]) -{ - tests_start_mpfr (); - - check_special(); - check_reftable (); - check_parse (); - check_overflow (); - check_retval (); - - tests_end_mpfr (); - return 0; -} - -void +static void check_special (void) { mpfr_t x, y; @@ -551,8 +530,7 @@ static struct dymmy_test { "1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"} }; - -void +static void check_reftable () { int i, base; @@ -597,7 +575,7 @@ check_reftable () mpfr_clear (x); } -void +static void check_parse (void) { mpfr_t x; @@ -951,3 +929,46 @@ check_retval (void) mpfr_clear (x); } + +/* Bug found by Christoph Lauter (in mpfr_set_str). */ +static void +bug20081028 (void) +{ + mpfr_t x; + const char *s = "0.10000000000000000000000000000001E1"; + int res, err = 0; + + mpfr_init2 (x, 32); + res = mpfr_strtofr (x, "1.00000000000000000006", NULL, 10, GMP_RNDU); + if (res <= 0) + { + printf ("Error in bug20081028: expected positive ternary value," + " got %d\n", res); + err = 1; + } + if (! mpfr_greater_p (x, __gmpfr_one)) + { + printf ("Error in bug20081028:\nExpected %s\nGot ", s); + mpfr_dump (x); + err = 1; + } + mpfr_clear (x); + if (err) + exit (1); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_special(); + check_reftable (); + check_parse (); + check_overflow (); + check_retval (); + bug20081028 (); + + tests_end_mpfr (); + return 0; +} |