[06beb7a] | 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 | +} |
---|