summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-11 08:49:53 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-11 08:49:53 +0000
commitf20af9ca82951de058e2a1a2145f8504b1e58eb5 (patch)
treea2843dc5ff9cbac9d81ffc88ef46a16a3ce62bde
parent7fc5ba57421ec12357add79068260896e38b1817 (diff)
downloadmpfr-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.c22
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 */