summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-01-16 19:48:19 +0000
committerMike Frysinger <vapier@gentoo.org>2009-01-16 19:48:19 +0000
commit0bf0b4eaf51e7d0f70a44d5853d8a3435fc5736a (patch)
treef82976d489bc9e31304dda5512e6a5071a0d072a /dev-libs/mpfr
parentold (diff)
downloadgentoo-2-0bf0b4eaf51e7d0f70a44d5853d8a3435fc5736a.tar.gz
gentoo-2-0bf0b4eaf51e7d0f70a44d5853d8a3435fc5736a.tar.bz2
gentoo-2-0bf0b4eaf51e7d0f70a44d5853d8a3435fc5736a.zip
Grab upstream fixes for upstream bug 6604.
(Portage version: 2.2_rc20/cvs/Linux 2.6.28 x86_64)
Diffstat (limited to 'dev-libs/mpfr')
-rw-r--r--dev-libs/mpfr/ChangeLog11
-rw-r--r--dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5664.patch180
-rw-r--r--dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5752.patch389
-rw-r--r--dev-libs/mpfr/mpfr-2.3.2-r1.ebuild49
4 files changed, 627 insertions, 2 deletions
diff --git a/dev-libs/mpfr/ChangeLog b/dev-libs/mpfr/ChangeLog
index dbef1b1635d7..83b2e4b7925e 100644
--- a/dev-libs/mpfr/ChangeLog
+++ b/dev-libs/mpfr/ChangeLog
@@ -1,6 +1,13 @@
# ChangeLog for dev-libs/mpfr
-# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/dev-libs/mpfr/ChangeLog,v 1.83 2008/11/28 13:18:42 aballier Exp $
+# Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/dev-libs/mpfr/ChangeLog,v 1.84 2009/01/16 19:48:19 vapier Exp $
+
+*mpfr-2.3.2-r1 (16 Jan 2009)
+
+ 16 Jan 2009; Mike Frysinger <vapier@gentoo.org>
+ +files/2.3.2/mpfr-2.3.2-svn5664.patch,
+ +files/2.3.2/mpfr-2.3.2-svn5752.patch, +mpfr-2.3.2-r1.ebuild:
+ Grab upstream fixes for upstream bug 6604.
28 Nov 2008; Alexis Ballier <aballier@gentoo.org> mpfr-2.3.2.ebuild:
fix find call for bsd find compatibility, bug #236067
diff --git a/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5664.patch b/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5664.patch
new file mode 100644
index 000000000000..e71022dc0584
--- /dev/null
+++ b/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5664.patch
@@ -0,0 +1,180 @@
+fix from upstream:
+
+Incorrect directed rounding in mpfr_strtofr. In mpfr_strtofr, rounding
+"1.00000000000000000006" upward to 32 bits returns 1 with ternary value 0
+instead of 1+ with positive ternary value. This bug also affects the result of
+mpfr_set_str (as it is based on mpfr_strtofr).
+[Changesets: 5664 5752]
+
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=6604&group_id=136&atid=619
+
+Index: branches/2.3/strtofr.c
+===================================================================
+--- branches/2.3/strtofr.c (revision 5663)
++++ branches/2.3/strtofr.c (revision 5664)
+@@ -473,7 +473,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+
+ 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
+ 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,
+Index: branches/2.3/tests/tstrtofr.c
+===================================================================
+--- branches/2.3/tests/tstrtofr.c (revision 5663)
++++ branches/2.3/tests/tstrtofr.c (revision 5664)
+@@ -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;
++}
+Index: branches/2.3/tests/tset_str.c
+===================================================================
+--- branches/2.3/tests/tset_str.c (revision 5663)
++++ branches/2.3/tests/tset_str.c (revision 5664)
+@@ -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/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5752.patch b/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5752.patch
new file mode 100644
index 000000000000..82f2b5bda411
--- /dev/null
+++ b/dev-libs/mpfr/files/2.3.2/mpfr-2.3.2-svn5752.patch
@@ -0,0 +1,389 @@
+fix from upstream:
+
+Incorrect directed rounding in mpfr_strtofr. In mpfr_strtofr, rounding
+"1.00000000000000000006" upward to 32 bits returns 1 with ternary value 0
+instead of 1+ with positive ternary value. This bug also affects the result of
+mpfr_set_str (as it is based on mpfr_strtofr).
+[Changesets: 5664 5752]
+
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=6604&group_id=136&atid=619
+
+Index: branches/2.3/strtofr.c
+===================================================================
+--- branches/2.3/strtofr.c (revision 5751)
++++ branches/2.3/strtofr.c (revision 5752)
+@@ -31,14 +31,24 @@ MA 02110-1301, USA. */
+ #define MPFR_MAX_BASE 62
+
+ struct parsed_string {
+- int negative;
+- int base;
+- unsigned char *mantissa, *mant;
+- size_t prec, alloc;
+- mp_exp_t exp_base, exp_bin;
++ int negative; /* non-zero iff the number is negative */
++ int base; /* base of the string */
++ unsigned char *mantissa; /* raw significand (without any point) */
++ unsigned char *mant; /* stripped significand (without starting and
++ ending zeroes) */
++ size_t prec; /* length of mant (zero for +/-0) */
++ size_t alloc; /* allocation size of mantissa */
++ mp_exp_t exp_base; /* number of digits before the point */
++ mp_exp_t exp_bin; /* exponent in case base=2 or 16, and the pxxx
++ format is used (i.e., exponent is given in
++ base 10) */
+ };
+
+-/* This table has been generated by the following program */
++/* This table has been generated by the following program.
++ For 2 <= b <= MPFR_MAX_BASE,
++ RedInvLog2Table[b-2][0] / RedInvLog2Table[b-2][1]
++ is an upper approximation of log(2)/log(b).
++*/
+ static const unsigned long RedInvLog2Table[MPFR_MAX_BASE-1][2] = {
+ {1UL, 1UL},
+ {53UL, 84UL},
+@@ -441,7 +451,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ MPFR_ZIV_DECL (loop);
+ MPFR_TMP_DECL (marker);
+
+- /* determine the minimal precision for the computation */
++ /* initialize the working precision */
+ prec = MPFR_PREC (x) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (x));
+
+ /* compute y as long as rounding is not possible */
+@@ -449,60 +459,88 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+- /* initialize y to the value of 0.mant_s[0]...mant_s[pr-1] */
++ /* Set y to the value of the ~prec most significant bits of pstr->mant
++ (as long as we guarantee correct rounding, we don't need to get
++ exactly prec bits). */
+ ysize = (prec - 1) / BITS_PER_MP_LIMB + 1;
++ /* prec bits corresponds to ysize limbs */
+ ysize_bits = ysize * BITS_PER_MP_LIMB;
++ /* and to ysize_bits >= prec > MPFR_PREC (x) bits */
+ y = (mp_limb_t*) MPFR_TMP_ALLOC ((2 * ysize + 1) * sizeof (mp_limb_t));
+- y += ysize;
++ y += ysize; /* y has (ysize+1) allocated limbs */
+
+- /* required precision for str to have ~ysize limbs
+- We must have (2^(BITS_PER_MP_LIMB))^ysize ~= base^pstr_size
+- aka pstr_size = ceil (ysize*BITS_PER_MP_LIMB/log2(base))
+- ysize ~ prec/BITS_PER_MP_LIMB and prec < Umax/2 =>
++ /* pstr_size is the number of characters we read in pstr->mant
++ to have at least ysize full limbs.
++ We must have base^(pstr_size-1) >= (2^(BITS_PER_MP_LIMB))^ysize
++ (in the worst case, the first digit is one and all others are zero).
++ i.e., pstr_size >= 1 + ysize*BITS_PER_MP_LIMB/log2(base)
++ Since ysize ~ prec/BITS_PER_MP_LIMB and prec < Umax/2 =>
+ ysize*BITS_PER_MP_LIMB can not overflow.
+- Compute pstr_size = ysize_bits * Num / Den
+- Where Num/Den ~ 1/log2(base)
++ We compute pstr_size = 1 + ceil(ysize_bits * Num / Den)
++ where Num/Den >= 1/log2(base)
+ It is not exactly ceil(1/log2(base)) but could be one more (base 2)
+- Quite ugly since it tries to avoid overflow */
+- pstr_size = ( ysize_bits / RedInvLog2Table[pstr->base-2][1]
+- * RedInvLog2Table[pstr->base-2][0] )
+- + (( ysize_bits % RedInvLog2Table[pstr->base-2][1])
+- * RedInvLog2Table[pstr->base-2][0]
+- / RedInvLog2Table[pstr->base-2][1] )
+- + 1;
++ Quite ugly since it tries to avoid overflow:
++ let Num = RedInvLog2Table[pstr->base-2][0]
++ and Den = RedInvLog2Table[pstr->base-2][1],
++ and ysize_bits = a*Den+b,
++ then ysize_bits * Num/Den = a*Num + (b * Num)/Den,
++ thus ceil(ysize_bits * Num/Den) = a*Num + floor(b * Num + Den - 1)/Den
++ */
++ {
++ unsigned long Num = RedInvLog2Table[pstr->base-2][0];
++ unsigned long Den = RedInvLog2Table[pstr->base-2][1];
++ pstr_size = ((ysize_bits / Den) * Num)
++ + (((ysize_bits % Den) * Num + Den - 1) / Den)
++ + 1;
++ }
++
++ /* since pstr_size corresponds to at least ysize_bits full bits,
++ and ysize_bits > prec, the weight of the neglected part of
++ pstr->mant (if any) is < ulp(y) < ulp(x) */
+
++ /* if the number of wanted characters is more than what we have in
++ pstr->mant, round it down */
+ if (pstr_size >= pstr->prec)
+ pstr_size = pstr->prec;
+ MPFR_ASSERTD (pstr_size == (mp_exp_t) pstr_size);
+
+- /* convert str into binary */
++ /* 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+1);
+
+ /* normalize y: warning we can get even get ysize+1 limbs! */
+- MPFR_ASSERTD (y[real_ysize - 1] != 0);
++ MPFR_ASSERTD (y[real_ysize - 1] != 0); /* mpn_set_str guarantees this */
+ count_leading_zeros (count, y[real_ysize - 1]);
+- exact = (real_ysize <= ysize);
+- if (exact != 0) /* shift y to the left in that case y should be exact */
++ /* exact means that the number of limbs of the output of mpn_set_str
++ is less or equal to ysize */
++ exact = real_ysize <= ysize;
++ if (exact) /* shift y to the left in that case y should be exact */
+ {
++ /* we have enough limbs to store {y, real_ysize} */
+ /* shift {y, num_limb} for count bits to the left */
+ if (count != 0)
+- mpn_lshift (y, y, real_ysize, count);
+- /* shift {y, num_limb} for (ysize-num_limb) limbs to the left */
++ mpn_lshift (y + ysize - real_ysize, y, real_ysize, count);
+ if (real_ysize != ysize)
+ {
+- MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
++ if (count == 0)
++ MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
+ MPN_ZERO (y, ysize - real_ysize);
+ }
+ /* for each bit shift decrease exponent of y */
+ /* (This should not overflow) */
+ exp = - ((ysize - real_ysize) * BITS_PER_MP_LIMB + count);
+ }
+- else /* shift y for the right */
++ else /* shift y to the right, by doing this we might lose some
++ bits from the result of mpn_set_str (in addition to the
++ characters neglected from pstr->mant) */
+ {
+ /* shift {y, num_limb} for (BITS_PER_MP_LIMB - count) bits
+- to the right */
+- mpn_rshift (y, y, real_ysize, BITS_PER_MP_LIMB - count);
++ to the right. FIXME: can we prove that count cannot be zero here,
++ since mpn_rshift does not accept a shift of BITS_PER_MP_LIMB? */
++ MPFR_ASSERTD (count != 0);
++ exact = mpn_rshift (y, y, real_ysize, BITS_PER_MP_LIMB - count) ==
++ MPFR_LIMB_ZERO;
+ /* for each bit shift increase exponent of y */
+ exp = BITS_PER_MP_LIMB - count;
+ }
+@@ -542,7 +580,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ result = y;
+ err = 0;
+ }
+- /* case pstr->exp_base > pstr_size */
++ /* case non-power-of-two-base, and pstr->exp_base > pstr_size */
+ else if (pstr->exp_base > (mp_exp_t) pstr_size)
+ {
+ mp_limb_t *z;
+@@ -559,6 +597,13 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ goto overflow;
+ exact = exact && (err == -1);
+
++ /* If exact is non zero, then z equals exactly the value of the
++ pstr_size most significant digits from pstr->mant, i.e., the
++ only difference can come from the neglected pstr->prec-pstr_size
++ least significant digits of pstr->mant.
++ If exact is zero, then z is rounded towards zero with respect
++ to that value. */
++
+ /* multiply(y = 0.mant_s[0]...mant_s[pr-1])_base by base^(exp_s-g) */
+ mpn_mul_n (result, y, z, ysize);
+
+@@ -588,6 +633,8 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ exp --;
+ }
+
++ /* if the low ysize limbs of {result, 2*ysize} are all zero,
++ then the result is still "exact" (if it was before) */
+ exact = exact && (mpn_scan1 (result, 0)
+ >= (unsigned long) ysize_bits);
+ result += ysize;
+@@ -598,7 +645,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ mp_limb_t *z;
+ mp_exp_t exp_z;
+
+- result = (mp_limb_t*) MPFR_TMP_ALLOC ( (3*ysize+1) * BYTES_PER_MP_LIMB);
++ result = (mp_limb_t*) MPFR_TMP_ALLOC ((3*ysize+1) * BYTES_PER_MP_LIMB);
+
+ /* set y to y * K^ysize */
+ y = y - ysize; /* we have allocated ysize limbs at y - ysize */
+@@ -622,7 +669,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ /* compute y / z */
+ /* result will be put into result + n, and remainder into result */
+ mpn_tdiv_qr (result + ysize, result, (mp_size_t) 0, y,
+- 2*ysize, z, ysize);
++ 2 * ysize, z, ysize);
+
+ /* exp -= exp_z + ysize_bits with overflow checking
+ and check that we can add/substract 2 to exp without overflow */
+@@ -635,6 +682,8 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ MPFR_EXP_MIN+2, MPFR_EXP_MAX-2,
+ goto overflow, goto underflow);
+ err += 2;
++ /* if the remainder of the division is zero, then the result is
++ still "exact" if it was before */
+ exact = exact && (mpn_popcount (result, ysize) == 0);
+
+ /* normalize result */
+@@ -648,7 +697,7 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ }
+ result += ysize;
+ }
+- /* case exp_base = pstr_size */
++ /* case exp_base = pstr_size: no multiplication or division needed */
+ else
+ {
+ /* base^(exp_s-pr) = 1 nothing to compute */
+@@ -656,18 +705,16 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ 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;
+- }
++ /* If result is exact, we still have to consider the neglected part
++ of the input string. For a directed rounding, in that case we could
++ still correctly round, since the neglected part is less than
++ one ulp, but that would make the code more complex, and give a
++ speedup for rare cases only. */
++ exact = exact && (pstr_size == pstr->prec);
++
++ /* at this point, result is an approximation rounded towards zero
++ of the pstr_size most significant digits of pstr->mant, with
++ equality in case exact is non-zero. */
+
+ /* test if rounding is possible, and if so exit the loop */
+ if (exact || mpfr_can_round_raw (result, ysize,
+@@ -692,6 +739,13 @@ parsed_string_to_mpfr (mpfr_t x, struct
+ exp ++;
+ }
+
++ if (res == 0) /* fix ternary value */
++ {
++ exact = exact && (pstr_size == pstr->prec);
++ if (!exact)
++ res = (pstr->negative) ? 1 : -1;
++ }
++
+ /* Set sign of x before exp since check_range needs a valid sign */
+ (pstr->negative) ? MPFR_SET_NEG (x) : MPFR_SET_POS (x);
+
+Index: branches/2.3/tests/tstrtofr.c
+===================================================================
+--- branches/2.3/tests/tstrtofr.c (revision 5751)
++++ branches/2.3/tests/tstrtofr.c (revision 5752)
+@@ -931,30 +931,88 @@ check_retval (void)
+ }
+
+ /* Bug found by Christoph Lauter (in mpfr_set_str). */
++static struct bug20081025_test {
++ mpfr_rnd_t rnd;
++ int inexact;
++ const char *str;
++ const char *binstr;
++} Bug20081028Table[] = {
++ {GMP_RNDN, -1, "1.00000000000000000006", "1"},
++ {GMP_RNDZ, -1, "1.00000000000000000006", "1"},
++ {GMP_RNDU, +1, "1.00000000000000000006",
++ "10000000000000000000000000000001e-31"},
++ {GMP_RNDD, -1, "1.00000000000000000006", "1"},
++
++
++ {GMP_RNDN, +1, "-1.00000000000000000006", "-1"},
++ {GMP_RNDZ, +1, "-1.00000000000000000006", "-1"},
++ {GMP_RNDU, +1, "-1.00000000000000000006", "-1"},
++ {GMP_RNDD, -1, "-1.00000000000000000006",
++ "-10000000000000000000000000000001e-31"},
++
++ {GMP_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"},
++ {GMP_RNDZ, -1, "0.999999999999999999999999999999999999999999999",
++ "11111111111111111111111111111111e-32"},
++ {GMP_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"},
++ {GMP_RNDD, -1, "0.999999999999999999999999999999999999999999999",
++ "11111111111111111111111111111111e-32"},
++
++ {GMP_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"},
++ {GMP_RNDZ, +1, "-0.999999999999999999999999999999999999999999999",
++ "-11111111111111111111111111111111e-32"},
++ {GMP_RNDU, +1, "-0.999999999999999999999999999999999999999999999",
++ "-11111111111111111111111111111111e-32"},
++ {GMP_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"}
++};
++
+ static void
+ bug20081028 (void)
+ {
+- mpfr_t x;
+- const char *s = "0.10000000000000000000000000000001E1";
+- int res, err = 0;
++ int i;
++ int inexact, res;
++ mpfr_rnd_t rnd;
++ mpfr_t x, y;
++ char *s;
+
+ 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))
++ mpfr_init2 (y, 32);
++ for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
+ {
+- printf ("Error in bug20081028:\nExpected %s\nGot ", s);
+- mpfr_dump (x);
+- err = 1;
++ rnd = Bug20081028Table[i].rnd;
++ inexact = Bug20081028Table[i].inexact;
++ mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
++ res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
++ if (s == NULL || *s != 0)
++ {
++ printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
++ "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
++ exit (1);
++ }
++ if (! SAME_SIGN (res, inexact))
++ {
++ printf ("Error in Bug20081028: expected %s ternary value, "
++ "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
++ inexact > 0 ? "positive" : "negative",
++ res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
++ mpfr_dump (x);
++ printf (" strtofr gives: ");
++ mpfr_dump (y);
++ exit (1);
++ }
++ if (mpfr_cmp (x, y))
++ {
++ printf ("Error in Bug20081028: Results differ between strtofr and "
++ "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
++ " Set binary gives: ",
++ i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
++ mpfr_dump (x);
++ printf (" strtofr gives: ");
++ mpfr_dump (y);
++ exit (1);
++ }
+ }
++ mpfr_clear (y);
+ mpfr_clear (x);
+- if (err)
+- exit (1);
+ }
+
+ int
diff --git a/dev-libs/mpfr/mpfr-2.3.2-r1.ebuild b/dev-libs/mpfr/mpfr-2.3.2-r1.ebuild
new file mode 100644
index 000000000000..ee56cbeedf4c
--- /dev/null
+++ b/dev-libs/mpfr/mpfr-2.3.2-r1.ebuild
@@ -0,0 +1,49 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-libs/mpfr/mpfr-2.3.2-r1.ebuild,v 1.1 2009/01/16 19:48:19 vapier Exp $
+
+# NOTE: we cannot depend on autotools here starting with gcc-4.3.x
+inherit eutils
+
+MY_PV=${PV/_p*}
+MY_P=${PN}-${MY_PV}
+PLEVEL=${PV/*p}
+DESCRIPTION="library for multiple-precision floating-point computations with exact rounding"
+HOMEPAGE="http://www.mpfr.org/"
+SRC_URI="http://www.mpfr.org/mpfr-current/${MY_P}.tar.lzma"
+
+LICENSE="LGPL-2.1"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~sparc-fbsd ~x86 ~x86-fbsd"
+IUSE=""
+
+RDEPEND=">=dev-libs/gmp-4.1.4-r2"
+DEPEND="${RDEPEND}
+ app-arch/lzma-utils"
+
+S=${WORKDIR}/${MY_P}
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+ [[ -d ${FILESDIR}/${PV} ]] && epatch "${FILESDIR}"/${PV}/*.patch
+ [[ ${PLEVEL} == ${PV} ]] && return 0
+ for ((i=1; i<=PLEVEL; ++i)) ; do
+ patch=patch$(printf '%02d' ${i})
+ if [[ -f ${FILESDIR}/${MY_PV}/${patch} ]] ; then
+ epatch "${FILESDIR}"/${MY_PV}/${patch}
+ elif [[ -f ${DISTDIR}/${PN}-${MY_PV}_p${i} ]] ; then
+ epatch "${DISTDIR}"/${PN}-${MY_PV}_p${i}
+ else
+ ewarn "${DISTDIR}/${PN}-${MY_PV}_p${i}"
+ die "patch ${i} missing - please report to bugs.gentoo.org"
+ fi
+ done
+ find . -type f -print0 | xargs -0 touch -r configure
+}
+
+src_install() {
+ emake install DESTDIR="${D}" || die
+ dodoc AUTHORS BUGS ChangeLog NEWS README TODO
+ dohtml *.html
+}