[c75433a] | 1 | Submitted By: Jim Gifford (jim at cross-lfs dot org)
|
---|
| 2 | Date: 2009-01-05
|
---|
| 3 | Initial Package Version: 2.3.2
|
---|
| 4 | Origin: MPFR Website
|
---|
| 5 | Upstream Status: Fixed
|
---|
| 6 | Description: See http://www.mpfr.org Website Under Bugs
|
---|
| 7 |
|
---|
| 8 | diff -Naur mpfr-2.3.2.orig/strtofr.c mpfr-2.3.2/strtofr.c
|
---|
| 9 | --- mpfr-2.3.2.orig/strtofr.c 2008-09-12 06:47:25.000000000 -0700
|
---|
| 10 | +++ mpfr-2.3.2/strtofr.c 2009-01-05 03:26:12.000000000 -0800
|
---|
| 11 | @@ -31,14 +31,24 @@
|
---|
| 12 | #define MPFR_MAX_BASE 62
|
---|
| 13 |
|
---|
| 14 | struct parsed_string {
|
---|
| 15 | - int negative;
|
---|
| 16 | - int base;
|
---|
| 17 | - unsigned char *mantissa, *mant;
|
---|
| 18 | - size_t prec, alloc;
|
---|
| 19 | - mp_exp_t exp_base, exp_bin;
|
---|
| 20 | + int negative; /* non-zero iff the number is negative */
|
---|
| 21 | + int base; /* base of the string */
|
---|
| 22 | + unsigned char *mantissa; /* raw significand (without any point) */
|
---|
| 23 | + unsigned char *mant; /* stripped significand (without starting and
|
---|
| 24 | + ending zeroes) */
|
---|
| 25 | + size_t prec; /* length of mant (zero for +/-0) */
|
---|
| 26 | + size_t alloc; /* allocation size of mantissa */
|
---|
| 27 | + mp_exp_t exp_base; /* number of digits before the point */
|
---|
| 28 | + mp_exp_t exp_bin; /* exponent in case base=2 or 16, and the pxxx
|
---|
| 29 | + format is used (i.e., exponent is given in
|
---|
| 30 | + base 10) */
|
---|
| 31 | };
|
---|
| 32 |
|
---|
| 33 | -/* This table has been generated by the following program */
|
---|
| 34 | +/* This table has been generated by the following program.
|
---|
| 35 | + For 2 <= b <= MPFR_MAX_BASE,
|
---|
| 36 | + RedInvLog2Table[b-2][0] / RedInvLog2Table[b-2][1]
|
---|
| 37 | + is an upper approximation of log(2)/log(b).
|
---|
| 38 | +*/
|
---|
| 39 | static const unsigned long RedInvLog2Table[MPFR_MAX_BASE-1][2] = {
|
---|
| 40 | {1UL, 1UL},
|
---|
| 41 | {53UL, 84UL},
|
---|
| 42 | @@ -441,7 +451,7 @@
|
---|
| 43 | MPFR_ZIV_DECL (loop);
|
---|
| 44 | MPFR_TMP_DECL (marker);
|
---|
| 45 |
|
---|
| 46 | - /* determine the minimal precision for the computation */
|
---|
| 47 | + /* initialize the working precision */
|
---|
| 48 | prec = MPFR_PREC (x) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (x));
|
---|
| 49 |
|
---|
| 50 | /* compute y as long as rounding is not possible */
|
---|
| 51 | @@ -449,60 +459,88 @@
|
---|
| 52 | MPFR_ZIV_INIT (loop, prec);
|
---|
| 53 | for (;;)
|
---|
| 54 | {
|
---|
| 55 | - /* initialize y to the value of 0.mant_s[0]...mant_s[pr-1] */
|
---|
| 56 | + /* Set y to the value of the ~prec most significant bits of pstr->mant
|
---|
| 57 | + (as long as we guarantee correct rounding, we don't need to get
|
---|
| 58 | + exactly prec bits). */
|
---|
| 59 | ysize = (prec - 1) / BITS_PER_MP_LIMB + 1;
|
---|
| 60 | + /* prec bits corresponds to ysize limbs */
|
---|
| 61 | ysize_bits = ysize * BITS_PER_MP_LIMB;
|
---|
| 62 | + /* and to ysize_bits >= prec > MPFR_PREC (x) bits */
|
---|
| 63 | y = (mp_limb_t*) MPFR_TMP_ALLOC ((2 * ysize + 1) * sizeof (mp_limb_t));
|
---|
| 64 | - y += ysize;
|
---|
| 65 | + y += ysize; /* y has (ysize+1) allocated limbs */
|
---|
| 66 |
|
---|
| 67 | - /* required precision for str to have ~ysize limbs
|
---|
| 68 | - We must have (2^(BITS_PER_MP_LIMB))^ysize ~= base^pstr_size
|
---|
| 69 | - aka pstr_size = ceil (ysize*BITS_PER_MP_LIMB/log2(base))
|
---|
| 70 | - ysize ~ prec/BITS_PER_MP_LIMB and prec < Umax/2 =>
|
---|
| 71 | + /* pstr_size is the number of characters we read in pstr->mant
|
---|
| 72 | + to have at least ysize full limbs.
|
---|
| 73 | + We must have base^(pstr_size-1) >= (2^(BITS_PER_MP_LIMB))^ysize
|
---|
| 74 | + (in the worst case, the first digit is one and all others are zero).
|
---|
| 75 | + i.e., pstr_size >= 1 + ysize*BITS_PER_MP_LIMB/log2(base)
|
---|
| 76 | + Since ysize ~ prec/BITS_PER_MP_LIMB and prec < Umax/2 =>
|
---|
| 77 | ysize*BITS_PER_MP_LIMB can not overflow.
|
---|
| 78 | - Compute pstr_size = ysize_bits * Num / Den
|
---|
| 79 | - Where Num/Den ~ 1/log2(base)
|
---|
| 80 | + We compute pstr_size = 1 + ceil(ysize_bits * Num / Den)
|
---|
| 81 | + where Num/Den >= 1/log2(base)
|
---|
| 82 | It is not exactly ceil(1/log2(base)) but could be one more (base 2)
|
---|
| 83 | - Quite ugly since it tries to avoid overflow */
|
---|
| 84 | - pstr_size = ( ysize_bits / RedInvLog2Table[pstr->base-2][1]
|
---|
| 85 | - * RedInvLog2Table[pstr->base-2][0] )
|
---|
| 86 | - + (( ysize_bits % RedInvLog2Table[pstr->base-2][1])
|
---|
| 87 | - * RedInvLog2Table[pstr->base-2][0]
|
---|
| 88 | - / RedInvLog2Table[pstr->base-2][1] )
|
---|
| 89 | - + 1;
|
---|
| 90 | + Quite ugly since it tries to avoid overflow:
|
---|
| 91 | + let Num = RedInvLog2Table[pstr->base-2][0]
|
---|
| 92 | + and Den = RedInvLog2Table[pstr->base-2][1],
|
---|
| 93 | + and ysize_bits = a*Den+b,
|
---|
| 94 | + then ysize_bits * Num/Den = a*Num + (b * Num)/Den,
|
---|
| 95 | + thus ceil(ysize_bits * Num/Den) = a*Num + floor(b * Num + Den - 1)/Den
|
---|
| 96 | + */
|
---|
| 97 | + {
|
---|
| 98 | + unsigned long Num = RedInvLog2Table[pstr->base-2][0];
|
---|
| 99 | + unsigned long Den = RedInvLog2Table[pstr->base-2][1];
|
---|
| 100 | + pstr_size = ((ysize_bits / Den) * Num)
|
---|
| 101 | + + (((ysize_bits % Den) * Num + Den - 1) / Den)
|
---|
| 102 | + + 1;
|
---|
| 103 | + }
|
---|
| 104 | +
|
---|
| 105 | + /* since pstr_size corresponds to at least ysize_bits full bits,
|
---|
| 106 | + and ysize_bits > prec, the weight of the neglected part of
|
---|
| 107 | + pstr->mant (if any) is < ulp(y) < ulp(x) */
|
---|
| 108 |
|
---|
| 109 | + /* if the number of wanted characters is more than what we have in
|
---|
| 110 | + pstr->mant, round it down */
|
---|
| 111 | if (pstr_size >= pstr->prec)
|
---|
| 112 | pstr_size = pstr->prec;
|
---|
| 113 | - MPFR_ASSERTD ((mp_exp_t) pstr_size == (mp_exp_t) pstr_size);
|
---|
| 114 | + MPFR_ASSERTD (pstr_size == (mp_exp_t) pstr_size);
|
---|
| 115 |
|
---|
| 116 | - /* convert str into binary */
|
---|
| 117 | + /* convert str into binary: note that pstr->mant is big endian,
|
---|
| 118 | + thus no offset is needed */
|
---|
| 119 | real_ysize = mpn_set_str (y, pstr->mant, pstr_size, pstr->base);
|
---|
| 120 | - MPFR_ASSERTD ( real_ysize <= ysize+1);
|
---|
| 121 | + MPFR_ASSERTD (real_ysize <= ysize+1);
|
---|
| 122 |
|
---|
| 123 | /* normalize y: warning we can get even get ysize+1 limbs! */
|
---|
| 124 | - MPFR_ASSERTD (y[real_ysize - 1] != 0);
|
---|
| 125 | + MPFR_ASSERTD (y[real_ysize - 1] != 0); /* mpn_set_str guarantees this */
|
---|
| 126 | count_leading_zeros (count, y[real_ysize - 1]);
|
---|
| 127 | - exact = (real_ysize <= ysize);
|
---|
| 128 | - if (exact != 0) /* shift y to the left in that case y should be exact */
|
---|
| 129 | + /* exact means that the number of limbs of the output of mpn_set_str
|
---|
| 130 | + is less or equal to ysize */
|
---|
| 131 | + exact = real_ysize <= ysize;
|
---|
| 132 | + if (exact) /* shift y to the left in that case y should be exact */
|
---|
| 133 | {
|
---|
| 134 | + /* we have enough limbs to store {y, real_ysize} */
|
---|
| 135 | /* shift {y, num_limb} for count bits to the left */
|
---|
| 136 | if (count != 0)
|
---|
| 137 | - mpn_lshift (y, y, real_ysize, count);
|
---|
| 138 | - /* shift {y, num_limb} for (ysize-num_limb) limbs to the left */
|
---|
| 139 | + mpn_lshift (y + ysize - real_ysize, y, real_ysize, count);
|
---|
| 140 | if (real_ysize != ysize)
|
---|
| 141 | {
|
---|
| 142 | - MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
|
---|
| 143 | + if (count == 0)
|
---|
| 144 | + MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
|
---|
| 145 | MPN_ZERO (y, ysize - real_ysize);
|
---|
| 146 | }
|
---|
| 147 | /* for each bit shift decrease exponent of y */
|
---|
| 148 | /* (This should not overflow) */
|
---|
| 149 | exp = - ((ysize - real_ysize) * BITS_PER_MP_LIMB + count);
|
---|
| 150 | }
|
---|
| 151 | - else /* shift y for the right */
|
---|
| 152 | + else /* shift y to the right, by doing this we might lose some
|
---|
| 153 | + bits from the result of mpn_set_str (in addition to the
|
---|
| 154 | + characters neglected from pstr->mant) */
|
---|
| 155 | {
|
---|
| 156 | /* shift {y, num_limb} for (BITS_PER_MP_LIMB - count) bits
|
---|
| 157 | - to the right */
|
---|
| 158 | - mpn_rshift (y, y, real_ysize, BITS_PER_MP_LIMB - count);
|
---|
| 159 | + to the right. FIXME: can we prove that count cannot be zero here,
|
---|
| 160 | + since mpn_rshift does not accept a shift of BITS_PER_MP_LIMB? */
|
---|
| 161 | + MPFR_ASSERTD (count != 0);
|
---|
| 162 | + exact = mpn_rshift (y, y, real_ysize, BITS_PER_MP_LIMB - count) ==
|
---|
| 163 | + MPFR_LIMB_ZERO;
|
---|
| 164 | /* for each bit shift increase exponent of y */
|
---|
| 165 | exp = BITS_PER_MP_LIMB - count;
|
---|
| 166 | }
|
---|
| 167 | @@ -542,7 +580,7 @@
|
---|
| 168 | result = y;
|
---|
| 169 | err = 0;
|
---|
| 170 | }
|
---|
| 171 | - /* case pstr->exp_base > pstr_size */
|
---|
| 172 | + /* case non-power-of-two-base, and pstr->exp_base > pstr_size */
|
---|
| 173 | else if (pstr->exp_base > (mp_exp_t) pstr_size)
|
---|
| 174 | {
|
---|
| 175 | mp_limb_t *z;
|
---|
| 176 | @@ -559,6 +597,13 @@
|
---|
| 177 | goto overflow;
|
---|
| 178 | exact = exact && (err == -1);
|
---|
| 179 |
|
---|
| 180 | + /* If exact is non zero, then z equals exactly the value of the
|
---|
| 181 | + pstr_size most significant digits from pstr->mant, i.e., the
|
---|
| 182 | + only difference can come from the neglected pstr->prec-pstr_size
|
---|
| 183 | + least significant digits of pstr->mant.
|
---|
| 184 | + If exact is zero, then z is rounded towards zero with respect
|
---|
| 185 | + to that value. */
|
---|
| 186 | +
|
---|
| 187 | /* multiply(y = 0.mant_s[0]...mant_s[pr-1])_base by base^(exp_s-g) */
|
---|
| 188 | mpn_mul_n (result, y, z, ysize);
|
---|
| 189 |
|
---|
| 190 | @@ -588,6 +633,8 @@
|
---|
| 191 | exp --;
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 | + /* if the low ysize limbs of {result, 2*ysize} are all zero,
|
---|
| 195 | + then the result is still "exact" (if it was before) */
|
---|
| 196 | exact = exact && (mpn_scan1 (result, 0)
|
---|
| 197 | >= (unsigned long) ysize_bits);
|
---|
| 198 | result += ysize;
|
---|
| 199 | @@ -598,7 +645,7 @@
|
---|
| 200 | mp_limb_t *z;
|
---|
| 201 | mp_exp_t exp_z;
|
---|
| 202 |
|
---|
| 203 | - result = (mp_limb_t*) MPFR_TMP_ALLOC ( (3*ysize+1) * BYTES_PER_MP_LIMB);
|
---|
| 204 | + result = (mp_limb_t*) MPFR_TMP_ALLOC ((3*ysize+1) * BYTES_PER_MP_LIMB);
|
---|
| 205 |
|
---|
| 206 | /* set y to y * K^ysize */
|
---|
| 207 | y = y - ysize; /* we have allocated ysize limbs at y - ysize */
|
---|
| 208 | @@ -622,7 +669,7 @@
|
---|
| 209 | /* compute y / z */
|
---|
| 210 | /* result will be put into result + n, and remainder into result */
|
---|
| 211 | mpn_tdiv_qr (result + ysize, result, (mp_size_t) 0, y,
|
---|
| 212 | - 2*ysize, z, ysize);
|
---|
| 213 | + 2 * ysize, z, ysize);
|
---|
| 214 |
|
---|
| 215 | /* exp -= exp_z + ysize_bits with overflow checking
|
---|
| 216 | and check that we can add/substract 2 to exp without overflow */
|
---|
| 217 | @@ -635,6 +682,8 @@
|
---|
| 218 | MPFR_EXP_MIN+2, MPFR_EXP_MAX-2,
|
---|
| 219 | goto overflow, goto underflow);
|
---|
| 220 | err += 2;
|
---|
| 221 | + /* if the remainder of the division is zero, then the result is
|
---|
| 222 | + still "exact" if it was before */
|
---|
| 223 | exact = exact && (mpn_popcount (result, ysize) == 0);
|
---|
| 224 |
|
---|
| 225 | /* normalize result */
|
---|
| 226 | @@ -648,7 +697,7 @@
|
---|
| 227 | }
|
---|
| 228 | result += ysize;
|
---|
| 229 | }
|
---|
| 230 | - /* case exp_base = pstr_size */
|
---|
| 231 | + /* case exp_base = pstr_size: no multiplication or division needed */
|
---|
| 232 | else
|
---|
| 233 | {
|
---|
| 234 | /* base^(exp_s-pr) = 1 nothing to compute */
|
---|
| 235 | @@ -656,6 +705,17 @@
|
---|
| 236 | err = 0;
|
---|
| 237 | }
|
---|
| 238 |
|
---|
| 239 | + /* If result is exact, we still have to consider the neglected part
|
---|
| 240 | + of the input string. For a directed rounding, in that case we could
|
---|
| 241 | + still correctly round, since the neglected part is less than
|
---|
| 242 | + one ulp, but that would make the code more complex, and give a
|
---|
| 243 | + speedup for rare cases only. */
|
---|
| 244 | + exact = exact && (pstr_size == pstr->prec);
|
---|
| 245 | +
|
---|
| 246 | + /* at this point, result is an approximation rounded towards zero
|
---|
| 247 | + of the pstr_size most significant digits of pstr->mant, with
|
---|
| 248 | + equality in case exact is non-zero. */
|
---|
| 249 | +
|
---|
| 250 | /* test if rounding is possible, and if so exit the loop */
|
---|
| 251 | if (exact || mpfr_can_round_raw (result, ysize,
|
---|
| 252 | (pstr->negative) ? -1 : 1,
|
---|
| 253 | @@ -679,6 +739,13 @@
|
---|
| 254 | exp ++;
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | + if (res == 0) /* fix ternary value */
|
---|
| 258 | + {
|
---|
| 259 | + exact = exact && (pstr_size == pstr->prec);
|
---|
| 260 | + if (!exact)
|
---|
| 261 | + res = (pstr->negative) ? 1 : -1;
|
---|
| 262 | + }
|
---|
| 263 | +
|
---|
| 264 | /* Set sign of x before exp since check_range needs a valid sign */
|
---|
| 265 | (pstr->negative) ? MPFR_SET_NEG (x) : MPFR_SET_POS (x);
|
---|
| 266 |
|
---|
| 267 | diff -Naur mpfr-2.3.2.orig/tests/tset_str.c mpfr-2.3.2/tests/tset_str.c
|
---|
| 268 | --- mpfr-2.3.2.orig/tests/tset_str.c 2008-09-12 06:47:25.000000000 -0700
|
---|
| 269 | +++ mpfr-2.3.2/tests/tset_str.c 2009-01-05 03:25:12.000000000 -0800
|
---|
| 270 | @@ -81,6 +81,24 @@
|
---|
| 271 | mpfr_clear (a);
|
---|
| 272 | }
|
---|
| 273 |
|
---|
| 274 | +/* Bug found by Christoph Lauter. */
|
---|
| 275 | +static void
|
---|
| 276 | +bug20081028 (void)
|
---|
| 277 | +{
|
---|
| 278 | + mpfr_t x;
|
---|
| 279 | + const char *s = "0.10000000000000000000000000000001E1";
|
---|
| 280 | +
|
---|
| 281 | + mpfr_init2 (x, 32);
|
---|
| 282 | + mpfr_set_str (x, "1.00000000000000000006", 10, GMP_RNDU);
|
---|
| 283 | + if (! mpfr_greater_p (x, __gmpfr_one))
|
---|
| 284 | + {
|
---|
| 285 | + printf ("Error in bug20081028:\nExpected %s\nGot ", s);
|
---|
| 286 | + mpfr_dump (x);
|
---|
| 287 | + exit (1);
|
---|
| 288 | + }
|
---|
| 289 | + mpfr_clear (x);
|
---|
| 290 | +}
|
---|
| 291 | +
|
---|
| 292 | int
|
---|
| 293 | main (int argc, char *argv[])
|
---|
| 294 | {
|
---|
| 295 | @@ -845,6 +863,7 @@
|
---|
| 296 | mpfr_clear (y);
|
---|
| 297 |
|
---|
| 298 | check_underflow ();
|
---|
| 299 | + bug20081028 ();
|
---|
| 300 |
|
---|
| 301 | tests_end_mpfr ();
|
---|
| 302 | return 0;
|
---|
| 303 | diff -Naur mpfr-2.3.2.orig/tests/tstrtofr.c mpfr-2.3.2/tests/tstrtofr.c
|
---|
| 304 | --- mpfr-2.3.2.orig/tests/tstrtofr.c 2008-09-12 06:47:25.000000000 -0700
|
---|
| 305 | +++ mpfr-2.3.2/tests/tstrtofr.c 2009-01-05 03:26:12.000000000 -0800
|
---|
| 306 | @@ -27,28 +27,7 @@
|
---|
| 307 |
|
---|
| 308 | #include "mpfr-test.h"
|
---|
| 309 |
|
---|
| 310 | -static void check_reftable (void);
|
---|
| 311 | -static void check_special (void);
|
---|
| 312 | -static void check_retval (void);
|
---|
| 313 | -static void check_overflow (void);
|
---|
| 314 | -static void check_parse (void);
|
---|
| 315 | -
|
---|
| 316 | -int
|
---|
| 317 | -main (int argc, char *argv[])
|
---|
| 318 | -{
|
---|
| 319 | - tests_start_mpfr ();
|
---|
| 320 | -
|
---|
| 321 | - check_special();
|
---|
| 322 | - check_reftable ();
|
---|
| 323 | - check_parse ();
|
---|
| 324 | - check_overflow ();
|
---|
| 325 | - check_retval ();
|
---|
| 326 | -
|
---|
| 327 | - tests_end_mpfr ();
|
---|
| 328 | - return 0;
|
---|
| 329 | -}
|
---|
| 330 | -
|
---|
| 331 | -void
|
---|
| 332 | +static void
|
---|
| 333 | check_special (void)
|
---|
| 334 | {
|
---|
| 335 | mpfr_t x, y;
|
---|
| 336 | @@ -551,8 +530,7 @@
|
---|
| 337 | "1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"}
|
---|
| 338 | };
|
---|
| 339 |
|
---|
| 340 | -
|
---|
| 341 | -void
|
---|
| 342 | +static void
|
---|
| 343 | check_reftable ()
|
---|
| 344 | {
|
---|
| 345 | int i, base;
|
---|
| 346 | @@ -597,7 +575,7 @@
|
---|
| 347 | mpfr_clear (x);
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 | -void
|
---|
| 351 | +static void
|
---|
| 352 | check_parse (void)
|
---|
| 353 | {
|
---|
| 354 | mpfr_t x;
|
---|
| 355 | @@ -951,3 +929,104 @@
|
---|
| 356 |
|
---|
| 357 | mpfr_clear (x);
|
---|
| 358 | }
|
---|
| 359 | +
|
---|
| 360 | +/* Bug found by Christoph Lauter (in mpfr_set_str). */
|
---|
| 361 | +static struct bug20081025_test {
|
---|
| 362 | + mpfr_rnd_t rnd;
|
---|
| 363 | + int inexact;
|
---|
| 364 | + const char *str;
|
---|
| 365 | + const char *binstr;
|
---|
| 366 | +} Bug20081028Table[] = {
|
---|
| 367 | + {GMP_RNDN, -1, "1.00000000000000000006", "1"},
|
---|
| 368 | + {GMP_RNDZ, -1, "1.00000000000000000006", "1"},
|
---|
| 369 | + {GMP_RNDU, +1, "1.00000000000000000006",
|
---|
| 370 | + "10000000000000000000000000000001e-31"},
|
---|
| 371 | + {GMP_RNDD, -1, "1.00000000000000000006", "1"},
|
---|
| 372 | +
|
---|
| 373 | +
|
---|
| 374 | + {GMP_RNDN, +1, "-1.00000000000000000006", "-1"},
|
---|
| 375 | + {GMP_RNDZ, +1, "-1.00000000000000000006", "-1"},
|
---|
| 376 | + {GMP_RNDU, +1, "-1.00000000000000000006", "-1"},
|
---|
| 377 | + {GMP_RNDD, -1, "-1.00000000000000000006",
|
---|
| 378 | + "-10000000000000000000000000000001e-31"},
|
---|
| 379 | +
|
---|
| 380 | + {GMP_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"},
|
---|
| 381 | + {GMP_RNDZ, -1, "0.999999999999999999999999999999999999999999999",
|
---|
| 382 | + "11111111111111111111111111111111e-32"},
|
---|
| 383 | + {GMP_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"},
|
---|
| 384 | + {GMP_RNDD, -1, "0.999999999999999999999999999999999999999999999",
|
---|
| 385 | + "11111111111111111111111111111111e-32"},
|
---|
| 386 | +
|
---|
| 387 | + {GMP_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"},
|
---|
| 388 | + {GMP_RNDZ, +1, "-0.999999999999999999999999999999999999999999999",
|
---|
| 389 | + "-11111111111111111111111111111111e-32"},
|
---|
| 390 | + {GMP_RNDU, +1, "-0.999999999999999999999999999999999999999999999",
|
---|
| 391 | + "-11111111111111111111111111111111e-32"},
|
---|
| 392 | + {GMP_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"}
|
---|
| 393 | +};
|
---|
| 394 | +
|
---|
| 395 | +static void
|
---|
| 396 | +bug20081028 (void)
|
---|
| 397 | +{
|
---|
| 398 | + int i;
|
---|
| 399 | + int inexact, res;
|
---|
| 400 | + mpfr_rnd_t rnd;
|
---|
| 401 | + mpfr_t x, y;
|
---|
| 402 | + char *s;
|
---|
| 403 | +
|
---|
| 404 | + mpfr_init2 (x, 32);
|
---|
| 405 | + mpfr_init2 (y, 32);
|
---|
| 406 | + for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
|
---|
| 407 | + {
|
---|
| 408 | + rnd = Bug20081028Table[i].rnd;
|
---|
| 409 | + inexact = Bug20081028Table[i].inexact;
|
---|
| 410 | + mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
|
---|
| 411 | + res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
|
---|
| 412 | + if (s == NULL || *s != 0)
|
---|
| 413 | + {
|
---|
| 414 | + printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
|
---|
| 415 | + "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
|
---|
| 416 | + exit (1);
|
---|
| 417 | + }
|
---|
| 418 | + if (! SAME_SIGN (res, inexact))
|
---|
| 419 | + {
|
---|
| 420 | + printf ("Error in Bug20081028: expected %s ternary value, "
|
---|
| 421 | + "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
|
---|
| 422 | + inexact > 0 ? "positive" : "negative",
|
---|
| 423 | + res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
|
---|
| 424 | + mpfr_dump (x);
|
---|
| 425 | + printf (" strtofr gives: ");
|
---|
| 426 | + mpfr_dump (y);
|
---|
| 427 | + exit (1);
|
---|
| 428 | + }
|
---|
| 429 | + if (mpfr_cmp (x, y))
|
---|
| 430 | + {
|
---|
| 431 | + printf ("Error in Bug20081028: Results differ between strtofr and "
|
---|
| 432 | + "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
|
---|
| 433 | + " Set binary gives: ",
|
---|
| 434 | + i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
|
---|
| 435 | + mpfr_dump (x);
|
---|
| 436 | + printf (" strtofr gives: ");
|
---|
| 437 | + mpfr_dump (y);
|
---|
| 438 | + exit (1);
|
---|
| 439 | + }
|
---|
| 440 | + }
|
---|
| 441 | + mpfr_clear (y);
|
---|
| 442 | + mpfr_clear (x);
|
---|
| 443 | +}
|
---|
| 444 | +
|
---|
| 445 | +int
|
---|
| 446 | +main (int argc, char *argv[])
|
---|
| 447 | +{
|
---|
| 448 | + tests_start_mpfr ();
|
---|
| 449 | +
|
---|
| 450 | + check_special();
|
---|
| 451 | + check_reftable ();
|
---|
| 452 | + check_parse ();
|
---|
| 453 | + check_overflow ();
|
---|
| 454 | + check_retval ();
|
---|
| 455 | + bug20081028 ();
|
---|
| 456 | +
|
---|
| 457 | + tests_end_mpfr ();
|
---|
| 458 | + return 0;
|
---|
| 459 | +}
|
---|