diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-11 08:49:53 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-11 08:49:53 +0000 |
commit | f20af9ca82951de058e2a1a2145f8504b1e58eb5 (patch) | |
tree | a2843dc5ff9cbac9d81ffc88ef46a16a3ce62bde | |
parent | 7fc5ba57421ec12357add79068260896e38b1817 (diff) | |
download | mpfr-f20af9ca82951de058e2a1a2145f8504b1e58eb5.tar.gz |
[src/strtofr.c] fix for 8-bit limb
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13167 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/strtofr.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/strtofr.c b/src/strtofr.c index 9ac116341..de5fdb119 100644 --- a/src/strtofr.c +++ b/src/strtofr.c @@ -545,7 +545,7 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd) /* convert str into binary: note that pstr->mant is big endian, thus no offset is needed */ real_ysize = mpn_set_str (y, pstr->mant, pstr_size, pstr->base); - MPFR_ASSERTD (real_ysize <= ysize+1); + MPFR_ASSERTD (real_ysize <= ysize + 2); /* normalize y: warning we can even get ysize+1 limbs! */ MPFR_ASSERTD (y[real_ysize - 1] != 0); /* mpn_set_str guarantees this */ @@ -573,17 +573,23 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd) bits from the result of mpn_set_str (in addition to the characters neglected from pstr->mant) */ { - /* shift {y, num_limb} for (GMP_NUMB_BITS - count) bits - to the right. - When calling mpfr_set_str (y, t, b, MPFR_RNDN) with prec(y)=12, b=54 - and t = 'rrMm@-99', with GMP_NUMB_BITS=8, we get count=0 here. */ + /* Shift {y, real_ysize} for (GMP_NUMB_BITS - count) bits + to the right, and put the ysize most significant limbs + into {y, ysize}. We have real_ysize = ysize or ysize + 1. */ if (count != 0) - exact = mpn_rshift (y, y, real_ysize, GMP_NUMB_BITS - count) == - MPFR_LIMB_ZERO; + { + exact = real_ysize == ysize + 1 || y[0] == MPFR_LIMB_ZERO; + /* mpn_rshift allows overlap, provided destination <= source */ + exact &= mpn_rshift (y, y + real_ysize - ysize - 1, real_ysize, + GMP_NUMB_BITS - count) == MPFR_LIMB_ZERO; + } else { - /* copy {y+1, real_ysize-1} to {y, real_ysize-1} */ + /* the case real_ysize = ysize + 2 with count = 0 cannot happen + even with GMP_NUMB_BITS = 8 since 62^2 < 256^2/2 */ + MPFR_ASSERTD(real_ysize == ysize + 1); exact = y[0] == MPFR_LIMB_ZERO; + /* copy {y+real_ysize-ysize, ysize} to {y, ysize} */ mpn_copyi (y, y + 1, real_ysize - 1); } /* for each bit shift increase exponent of y */ |