From 7d24682907fcf0fb237e9cdeb4c0ddd3a008eb6fe87d3a1e99ce57b7445b0cdf Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Wed, 12 Dec 2007 17:15:53 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mpfr?expand=0&rev=3 --- mpfr-2.3.0-patches.patch | 630 +++++++++++++++++++++++++++++++++++++++ mpfr.changes | 5 + mpfr.spec | 11 +- 3 files changed, 644 insertions(+), 2 deletions(-) create mode 100644 mpfr-2.3.0-patches.patch diff --git a/mpfr-2.3.0-patches.patch b/mpfr-2.3.0-patches.patch new file mode 100644 index 0000000..1b1546f --- /dev/null +++ b/mpfr-2.3.0-patches.patch @@ -0,0 +1,630 @@ +diff -Naurd mpfr-2.3.0-a/Makefile.am mpfr-2.3.0-b/Makefile.am +--- mpfr-2.3.0-a/Makefile.am 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/Makefile.am 2007-09-02 23:19:32.000000000 +0000 +@@ -32,8 +32,13 @@ + + MAKEINFOFLAGS = --enable-encoding + +-get_patches.c: PATCHES get_patches.sh +- ./get_patches.sh > $@ || rm -f $@ ++# Important note: If for some reason, srcdir is read-only at build time ++# (and you use objdir != srcdir), then you need to rebuild get_patches.c ++# (with "make get_patches.c") just after patching the MPFR source. This ++# should not be a problem in practice, in particular because "make dist" ++# automatically rebuilds get_patches.c before generating the archives. ++$(srcdir)/get_patches.c: PATCHES get_patches.sh ++ (cd $(srcdir) && ./get_patches.sh) > $@ || rm -f $@ + + # Do not add get_patches.c to CLEANFILES so that this file doesn't + # need to be (re)built as long as no patches are applied. Anyway the +diff -Naurd mpfr-2.3.0-a/Makefile.in mpfr-2.3.0-b/Makefile.in +--- mpfr-2.3.0-a/Makefile.in 2007-08-29 10:27:18.000000000 +0000 ++++ mpfr-2.3.0-b/Makefile.in 2007-09-02 23:59:30.000000000 +0000 +@@ -1665,8 +1665,13 @@ + uninstall-info-am uninstall-libLTLIBRARIES + + +-get_patches.c: PATCHES get_patches.sh +- ./get_patches.sh > $@ || rm -f $@ ++# Important note: If for some reason, srcdir is read-only at build time ++# (and you use objdir != srcdir), then you need to rebuild get_patches.c ++# (with "make get_patches.c") just after patching the MPFR source. This ++# should not be a problem in practice, in particular because "make dist" ++# automatically rebuilds get_patches.c before generating the archives. ++$(srcdir)/get_patches.c: PATCHES get_patches.sh ++ (cd $(srcdir) && ./get_patches.sh) > $@ || rm -f $@ + + tune: + $(MAKE) $(AM_MAKEFLAGS) tuneup$(EXEEXT) +diff -Naurd mpfr-2.3.0-a/PATCHES mpfr-2.3.0-b/PATCHES +--- mpfr-2.3.0-a/PATCHES 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/PATCHES 2007-09-02 23:59:50.000000000 +0000 +@@ -0,0 +1 @@ ++get_patches +diff -Naurd mpfr-2.3.0-a/VERSION mpfr-2.3.0-b/VERSION +--- mpfr-2.3.0-a/VERSION 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/VERSION 2007-09-02 23:55:55.000000000 +0000 +@@ -1 +1 @@ +-2.3.0 ++2.3.0-p1 +diff -Naurd mpfr-2.3.0-a/mpfr.h mpfr-2.3.0-b/mpfr.h +--- mpfr-2.3.0-a/mpfr.h 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/mpfr.h 2007-09-02 23:55:55.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 2 + #define MPFR_VERSION_MINOR 3 + #define MPFR_VERSION_PATCHLEVEL 0 +-#define MPFR_VERSION_STRING "2.3.0" ++#define MPFR_VERSION_STRING "2.3.0-p1" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-2.3.0-a/tests/tversion.c mpfr-2.3.0-b/tests/tversion.c +--- mpfr-2.3.0-a/tests/tversion.c 2007-08-29 10:18:10.000000000 +0000 ++++ mpfr-2.3.0-b/tests/tversion.c 2007-09-02 23:55:55.000000000 +0000 +@@ -46,7 +46,7 @@ + version = mpfr_get_version (); + + /* This test is disabled when a suffix (e.g. -dev) has been defined. */ +-#if 1 ++#if 0 + sprintf (buffer, "%d.%d.%d", MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, + MPFR_VERSION_PATCHLEVEL); + if (strcmp (buffer, version) != 0) +diff -Naurd mpfr-2.3.0-a/version.c mpfr-2.3.0-b/version.c +--- mpfr-2.3.0-a/version.c 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/version.c 2007-09-02 23:55:55.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "2.3.0"; ++ return "2.3.0-p1"; + } +diff -Naurd mpfr-2.3.0-a/PATCHES mpfr-2.3.0-b/PATCHES +--- mpfr-2.3.0-a/PATCHES 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/PATCHES 2007-09-03 00:03:46.000000000 +0000 +@@ -0,0 +1 @@ ++mpfr_acosh +diff -Naurd mpfr-2.3.0-a/VERSION mpfr-2.3.0-b/VERSION +--- mpfr-2.3.0-a/VERSION 2007-09-02 23:55:55.000000000 +0000 ++++ mpfr-2.3.0-b/VERSION 2007-09-03 00:02:12.000000000 +0000 +@@ -1 +1 @@ +-2.3.0-p1 ++2.3.0-p2 +diff -Naurd mpfr-2.3.0-a/acosh.c mpfr-2.3.0-b/acosh.c +--- mpfr-2.3.0-a/acosh.c 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/acosh.c 2007-08-31 17:20:08.000000000 +0000 +@@ -73,7 +73,7 @@ + /* Declaration of the size variables */ + mp_prec_t Ny = MPFR_PREC(y); /* Precision of output variable */ + mp_prec_t Nt; /* Precision of the intermediary variable */ +- mp_exp_t err, exp_te, exp_ti; /* Precision of error */ ++ mp_exp_t err, exp_te, d; /* Precision of error */ + MPFR_ZIV_DECL (loop); + + /* compute the precision of intermediary variable */ +@@ -91,13 +91,35 @@ + mpfr_mul (t, x, x, GMP_RNDD); /* x^2 */ + exp_te = MPFR_GET_EXP (t); + mpfr_sub_ui (t, t, 1, GMP_RNDD); /* x^2-1 */ +- exp_ti = MPFR_GET_EXP (t); +- mpfr_sqrt (t, t, GMP_RNDN); /* sqrt(x^2-1) */ +- mpfr_add (t, t, x, GMP_RNDN); /* sqrt(x^2-1)+x */ +- mpfr_log (t, t, GMP_RNDN); /* ln(sqrt(x^2-1)+x)*/ ++ if (MPFR_UNLIKELY (MPFR_IS_ZERO (t))) ++ { ++ mpfr_t z; ++ ++ /* This means that x is very close to 1: x = 1 + z with ++ z < 2^(-Nt). Instead of increasing the precision, let's ++ compute x^2-1 by (x+1)(x-1) with an accuracy of about ++ Nt bits. */ ++ mpfr_init2 (z, Nt); ++ mpfr_add_ui (t, x, 1, GMP_RNDD); ++ mpfr_sub_ui (z, x, 1, GMP_RNDD); ++ mpfr_mul (t, t, z, GMP_RNDD); ++ d = 2; ++ mpfr_sqrt (t, t, GMP_RNDN); /* sqrt(x^2-1) */ ++ mpfr_add (t, t, z, GMP_RNDN); /* sqrt(x^2-1)+z */ ++ mpfr_clear (z); ++ mpfr_log1p (t, t, GMP_RNDN); /* log1p(sqrt(x^2-1)+z) */ ++ } ++ else ++ { ++ d = exp_te - MPFR_GET_EXP (t); ++ d = MAX (1, d); ++ mpfr_sqrt (t, t, GMP_RNDN); /* sqrt(x^2-1) */ ++ mpfr_add (t, t, x, GMP_RNDN); /* sqrt(x^2-1)+x */ ++ mpfr_log (t, t, GMP_RNDN); /* ln(sqrt(x^2-1)+x) */ ++ } + + /* error estimate -- see algorithms.tex */ +- err = 3 + MAX (1, exp_te - exp_ti) - MPFR_GET_EXP(t); ++ err = 3 + d - MPFR_GET_EXP (t); + /* error is bounded by 1/2 + 2^err <= 2^(1+max(-1,err)) */ + err = 1 + MAX (-1, err); + if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Ny, rnd_mode))) +@@ -117,9 +139,3 @@ + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_check_range (y, inexact, rnd_mode); + } +- +- +- +- +- +- +diff -Naurd mpfr-2.3.0-a/mpfr.h mpfr-2.3.0-b/mpfr.h +--- mpfr-2.3.0-a/mpfr.h 2007-09-02 23:55:55.000000000 +0000 ++++ mpfr-2.3.0-b/mpfr.h 2007-09-03 00:02:12.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 2 + #define MPFR_VERSION_MINOR 3 + #define MPFR_VERSION_PATCHLEVEL 0 +-#define MPFR_VERSION_STRING "2.3.0-p1" ++#define MPFR_VERSION_STRING "2.3.0-p2" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-2.3.0-a/tests/tacosh.c mpfr-2.3.0-b/tests/tacosh.c +--- mpfr-2.3.0-a/tests/tacosh.c 2007-08-29 10:18:10.000000000 +0000 ++++ mpfr-2.3.0-b/tests/tacosh.c 2007-08-31 17:20:00.000000000 +0000 +@@ -123,12 +123,40 @@ + mpfr_clear (y); + } + ++/* With MPFR 2.3.0, this yields an assertion failure in mpfr_acosh. */ ++static void ++bug20070831 (void) ++{ ++ mpfr_t x, y, z; ++ int inex; ++ ++ mpfr_init2 (x, 256); ++ mpfr_init2 (y, 32); ++ mpfr_init2 (z, 32); ++ mpfr_set_ui (x, 1, GMP_RNDN); ++ mpfr_nextabove (x); ++ inex = mpfr_acosh (y, x, GMP_RNDZ); ++ mpfr_set_ui_2exp (z, 1, -127, GMP_RNDN); ++ mpfr_nextbelow (z); ++ MPFR_ASSERTN (inex < 0); ++ if (!mpfr_equal_p (y, z)) ++ { ++ printf ("Error in bug20070831:\nexpected "); ++ mpfr_dump (z); ++ printf ("got "); ++ mpfr_dump (y); ++ exit (1); ++ } ++ mpfr_clears (x, y, z, (void *) 0); ++} ++ + int + main (int argc, char *argv[]) + { + tests_start_mpfr (); + + special (); ++ bug20070831 (); + + test_generic (2, 100, 25); + +diff -Naurd mpfr-2.3.0-a/version.c mpfr-2.3.0-b/version.c +--- mpfr-2.3.0-a/version.c 2007-09-02 23:55:55.000000000 +0000 ++++ mpfr-2.3.0-b/version.c 2007-09-03 00:02:12.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "2.3.0-p1"; ++ return "2.3.0-p2"; + } +diff -Naurd mpfr-2.3.0-a/PATCHES mpfr-2.3.0-b/PATCHES +--- mpfr-2.3.0-a/PATCHES 2007-10-05 12:20:54.000000000 +0000 ++++ mpfr-2.3.0-b/PATCHES 2007-10-05 12:21:12.000000000 +0000 +@@ -0,0 +1 @@ ++mpfr_atan2 +diff -Naurd mpfr-2.3.0-a/VERSION mpfr-2.3.0-b/VERSION +--- mpfr-2.3.0-a/VERSION 2007-09-03 00:02:12.000000000 +0000 ++++ mpfr-2.3.0-b/VERSION 2007-10-05 12:21:06.000000000 +0000 +@@ -1 +1 @@ +-2.3.0-p2 ++2.3.0-p3 +diff -Naurd mpfr-2.3.0-a/atan2.c mpfr-2.3.0-b/atan2.c +--- mpfr-2.3.0-a/atan2.c 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/atan2.c 2007-10-05 12:21:01.000000000 +0000 +@@ -170,6 +170,7 @@ + /* use atan2(y,x) = atan(y/x) */ + for (;;) + { ++ mpfr_clear_flags (); + if (mpfr_div (tmp, y, x, GMP_RNDN) == 0) + { + /* Result is exact. */ +diff -Naurd mpfr-2.3.0-a/mpfr.h mpfr-2.3.0-b/mpfr.h +--- mpfr-2.3.0-a/mpfr.h 2007-09-03 00:02:12.000000000 +0000 ++++ mpfr-2.3.0-b/mpfr.h 2007-10-05 12:21:06.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 2 + #define MPFR_VERSION_MINOR 3 + #define MPFR_VERSION_PATCHLEVEL 0 +-#define MPFR_VERSION_STRING "2.3.0-p2" ++#define MPFR_VERSION_STRING "2.3.0-p3" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-2.3.0-a/tests/tatan.c mpfr-2.3.0-b/tests/tatan.c +--- mpfr-2.3.0-a/tests/tatan.c 2007-08-29 10:18:10.000000000 +0000 ++++ mpfr-2.3.0-b/tests/tatan.c 2007-10-05 12:21:01.000000000 +0000 +@@ -405,6 +405,40 @@ + mpfr_clears (a, x, y, (void *) 0); + } + ++/* Bug found by Robert Bajema (regression in MPFR 2.3.0). ++ The cause is the underflow flag set before the mpfr_atan2 call. */ ++static void ++atan2_bug_20071003 (void) ++{ ++ mpfr_t a, x, y, z; ++ ++ mpfr_inits (a, x, y, z, (void *) 0); ++ ++ mpfr_set_underflow (); ++ mpfr_set_str_binary (y, ++ "-0.10100110110100110111010110111111100110100010001110110E2"); ++ mpfr_set_str_binary (x, ++ "0.10100101010110010100010010111000110110011110001011110E3"); ++ mpfr_set_str_binary (z, ++ "-0.11101111001101101100111011001101000010010111101110110E-1"); ++ mpfr_atan2 (a, y, x, GMP_RNDN); ++ if (! mpfr_equal_p (a, z)) ++ { ++ printf ("mpfr_atan2 fails on:\n"); ++ printf (" y = "); ++ mpfr_dump (y); ++ printf (" x = "); ++ mpfr_dump (x); ++ printf ("Expected "); ++ mpfr_dump (z); ++ printf ("Got "); ++ mpfr_dump (a); ++ exit (1); ++ } ++ ++ mpfr_clears (a, x, y, z, (void *) 0); ++} ++ + int + main (int argc, char *argv[]) + { +@@ -414,6 +448,7 @@ + special (); + special_atan2 (); + smallvals_atan2 (); ++ atan2_bug_20071003 (); + + test_generic_atan (2, 200, 17); + test_generic_atan2 (2, 200, 17); +diff -Naurd mpfr-2.3.0-a/version.c mpfr-2.3.0-b/version.c +--- mpfr-2.3.0-a/version.c 2007-09-03 00:02:12.000000000 +0000 ++++ mpfr-2.3.0-b/version.c 2007-10-05 12:21:06.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "2.3.0-p2"; ++ return "2.3.0-p3"; + } +diff -Naurd mpfr-2.3.0-a/PATCHES mpfr-2.3.0-b/PATCHES +--- mpfr-2.3.0-a/PATCHES 2007-10-23 03:03:12.000000000 +0000 ++++ mpfr-2.3.0-b/PATCHES 2007-10-23 03:06:18.000000000 +0000 +@@ -0,0 +1 @@ ++mpfr_subnormalize +diff -Naurd mpfr-2.3.0-a/VERSION mpfr-2.3.0-b/VERSION +--- mpfr-2.3.0-a/VERSION 2007-10-05 12:21:06.000000000 +0000 ++++ mpfr-2.3.0-b/VERSION 2007-10-23 03:05:51.000000000 +0000 +@@ -1 +1 @@ +-2.3.0-p3 ++2.3.0-p4 +diff -Naurd mpfr-2.3.0-a/mpfr.h mpfr-2.3.0-b/mpfr.h +--- mpfr-2.3.0-a/mpfr.h 2007-10-05 12:21:06.000000000 +0000 ++++ mpfr-2.3.0-b/mpfr.h 2007-10-23 03:05:51.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 2 + #define MPFR_VERSION_MINOR 3 + #define MPFR_VERSION_PATCHLEVEL 0 +-#define MPFR_VERSION_STRING "2.3.0-p3" ++#define MPFR_VERSION_STRING "2.3.0-p4" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-2.3.0-a/mpfr.texi mpfr-2.3.0-b/mpfr.texi +--- mpfr-2.3.0-a/mpfr.texi 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/mpfr.texi 2007-10-23 03:05:25.000000000 +0000 +@@ -2038,7 +2038,8 @@ + @var{rnd} and @var{t} must be the used rounding mode for computing @var{x} + and the returned ternary value when computing @var{x}. + The subnormal exponent range is from @code{emin} to @code{emin+PREC(x)-1}. +-This functions assumes that @code{emax-emin >= PREC(x)}. ++If the result cannot be represented in the current exponent range ++(due to a too small @code{emax}), the behavior is undefined. + Note that unlike most functions, the result is compared to the exact one, + not the input value @var{x}, i.e.@: the ternary value is propagated. + This is a preliminary interface. +diff -Naurd mpfr-2.3.0-a/subnormal.c mpfr-2.3.0-b/subnormal.c +--- mpfr-2.3.0-a/subnormal.c 2007-08-29 10:18:11.000000000 +0000 ++++ mpfr-2.3.0-b/subnormal.c 2007-10-23 03:05:25.000000000 +0000 +@@ -26,10 +26,10 @@ + /* For GMP_RNDN, we can have a problem of double rounding. + In such a case, this table helps to conclude what to do (y positive): + Rounding Bit | Sticky Bit | inexact | Action | new inexact +- 0 | ? | ? | Trunc | sticky +- 1 | 0 | -1 | Trunc | ++ 0 | ? | ? | Trunc | sticky ++ 1 | 0 | 1 | Trunc | + 1 | 0 | 0 | Trunc if even | +- 1 | 0 | 1 | AddOneUlp | ++ 1 | 0 | -1 | AddOneUlp | + 1 | 1 | ? | AddOneUlp | + + For other rounding mode, there isn't such a problem. +@@ -41,8 +41,6 @@ + { + int inexact = 0; + +- MPFR_ASSERTD ((mpfr_uexp_t) __gmpfr_emax - __gmpfr_emin >= MPFR_PREC (y)); +- + /* The subnormal exponent range are from: + mpfr_emin to mpfr_emin + MPFR_PREC(y) - 1 */ + if (MPFR_LIKELY (MPFR_IS_SINGULAR (y) +@@ -69,23 +67,24 @@ + and use the previous table to conclude. */ + s = MPFR_LIMB_SIZE (y) - 1; + mant = MPFR_MANT (y) + s; +- rb = *mant & (MPFR_LIMB_HIGHBIT>>1); ++ rb = *mant & (MPFR_LIMB_HIGHBIT >> 1); + if (rb == 0) + goto set_min; +- sb = *mant & ((MPFR_LIMB_HIGHBIT>>1)-1); ++ sb = *mant & ((MPFR_LIMB_HIGHBIT >> 1) - 1); + while (sb == 0 && s-- != 0) + sb = *--mant; + if (sb != 0) + goto set_min_p1; + /* Rounding bit is 1 and sticky bit is 0. + We need to examine old inexact flag to conclude. */ +- if (old_inexact * MPFR_SIGN (y) < 0) ++ if ((old_inexact > 0 && MPFR_SIGN (y) > 0) || ++ (old_inexact < 0 && MPFR_SIGN (y) < 0)) + goto set_min; +- /* If inexact != 0, return 0.1*2^emin+1. ++ /* If inexact != 0, return 0.1*2^(emin+1). + Otherwise, rounding bit = 1, sticky bit = 0 and inexact = 0 +- So we have 0.1100000000000000000000000*2^emin exactly!!! +- we choose to return 0.1*2^emin+1 which minimizes the relative +- error. */ ++ So we have 0.1100000000000000000000000*2^emin exactly. ++ We return 0.1*2^(emin+1) according to the even-rounding ++ rule on subnormals. */ + goto set_min_p1; + } + else if (MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))) +@@ -97,7 +96,8 @@ + else + { + set_min_p1: +- mpfr_setmin (y, __gmpfr_emin+1); ++ /* Note: mpfr_setmin will abort if __gmpfr_emax == __gmpfr_emin. */ ++ mpfr_setmin (y, __gmpfr_emin + 1); + inexact = MPFR_SIGN (y); + } + } +@@ -120,15 +120,17 @@ + MPFR_SET_EXP (dest, MPFR_GET_EXP (dest)+1)); + if (MPFR_LIKELY (old_inexact != 0)) + { +- if (MPFR_UNLIKELY(rnd==GMP_RNDN && (inexact == MPFR_EVEN_INEX +- || inexact == -MPFR_EVEN_INEX))) ++ if (MPFR_UNLIKELY(rnd == GMP_RNDN && (inexact == MPFR_EVEN_INEX ++ || inexact == -MPFR_EVEN_INEX))) + { +- if (old_inexact*inexact*MPFR_INT_SIGN (y) > 0) ++ /* if both roundings are in the same direction, we have to go ++ back in the other direction */ ++ if (SAME_SIGN (inexact, old_inexact)) + { +- if (inexact < 0) +- mpfr_nexttoinf (dest); +- else ++ if (SAME_SIGN (inexact, MPFR_INT_SIGN (y))) + mpfr_nexttozero (dest); ++ else ++ mpfr_nexttoinf (dest); + inexact = -inexact; + } + } +@@ -136,7 +138,8 @@ + inexact = old_inexact; + } + old_inexact = mpfr_set (y, dest, rnd); +- MPFR_ASSERTD (old_inexact == 0); ++ MPFR_ASSERTN (old_inexact == 0); ++ MPFR_ASSERTN (MPFR_IS_PURE_FP (y)); + mpfr_clear (dest); + } + return inexact; +diff -Naurd mpfr-2.3.0-a/tests/tsubnormal.c mpfr-2.3.0-b/tests/tsubnormal.c +--- mpfr-2.3.0-a/tests/tsubnormal.c 2007-08-29 10:18:09.000000000 +0000 ++++ mpfr-2.3.0-b/tests/tsubnormal.c 2007-10-23 03:05:25.000000000 +0000 +@@ -22,6 +22,7 @@ + + #include + #include ++#include + + #include "mpfr-test.h" + +@@ -41,6 +42,8 @@ + {"0.11001E-10", 0, GMP_RNDZ, "0.1E-10"}, + {"0.11001E-10", 0, GMP_RNDU, "0.1E-9"}, + {"0.11000E-10", 0, GMP_RNDN, "0.1E-9"}, ++ {"0.11000E-10", -1, GMP_RNDN, "0.1E-9"}, ++ {"0.11000E-10", 1, GMP_RNDN, "0.1E-10"}, + {"0.11111E-8", 0, GMP_RNDN, "0.10E-7"}, + {"0.10111E-8", 0, GMP_RNDN, "0.11E-8"}, + {"0.11110E-8", -1, GMP_RNDN, "0.10E-7"}, +@@ -51,7 +54,7 @@ + check1 (void) + { + mpfr_t x; +- int i, j; ++ int i, j, k, s, old_inex; + + mpfr_set_default_prec (9); + mpfr_set_emin (-10); +@@ -59,20 +62,115 @@ + + mpfr_init (x); + for (i = 0; i < (sizeof (tab) / sizeof (tab[0])); i++) +- { +- mpfr_set_str (x, tab[i].in, 2, GMP_RNDN); +- j = mpfr_subnormalize (x, tab[i].i, tab[i].rnd); +- if (mpfr_cmp_str (x, tab[i].out, 2, GMP_RNDN) != 0) ++ for (s = 0; s <= (tab[i].rnd == GMP_RNDN); s++) ++ for (k = 0; k <= 1; k++) + { +- printf ("Error for i=%d\nFor:%s\nExpected:%s\nGot:", +- i, tab[i].in, tab[i].out); +- mpfr_dump (x); +- exit (1); ++ mpfr_set_str (x, tab[i].in, 2, GMP_RNDN); ++ old_inex = tab[i].i; ++ if (s) ++ { ++ mpfr_neg (x, x, GMP_RNDN); ++ old_inex = - old_inex; ++ } ++ if (k && old_inex) ++ old_inex = old_inex < 0 ? INT_MIN : INT_MAX; ++ j = mpfr_subnormalize (x, old_inex, tab[i].rnd); ++ /* TODO: test j. */ ++ if (s) ++ mpfr_neg (x, x, GMP_RNDN); ++ if (mpfr_cmp_str (x, tab[i].out, 2, GMP_RNDN) != 0) ++ { ++ char *sgn = s ? "-" : ""; ++ printf ("Error for i = %d (old_inex = %d), k = %d, x = %s%s\n" ++ "Expected: %s%s\nGot: ", i, old_inex, k, ++ sgn, tab[i].in, sgn, tab[i].out); ++ if (s) ++ mpfr_neg (x, x, GMP_RNDN); ++ mpfr_dump (x); ++ exit (1); ++ } + } +- } + mpfr_clear (x); + } + ++/* bug found by Kevin P. Rauch on 22 Oct 2007 */ ++static void ++check2 (void) ++{ ++ mpfr_t x, y, z; ++ int tern; ++ ++ mpfr_init2 (x, 32); ++ mpfr_init2 (y, 32); ++ mpfr_init2 (z, 32); ++ ++ mpfr_set_ui (x, 0xC0000000U, GMP_RNDN); ++ mpfr_neg (x, x, GMP_RNDN); ++ mpfr_set_ui (y, 0xFFFFFFFEU, GMP_RNDN); ++ mpfr_set_exp (x, 0); ++ mpfr_set_exp (y, 0); ++ mpfr_set_emin (-29); ++ ++ tern = mpfr_mul (z, x, y, GMP_RNDN); ++ /* z = -0.BFFFFFFE, tern > 0 */ ++ ++ tern = mpfr_subnormalize (z, tern, GMP_RNDN); ++ /* z should be -0.75 */ ++ MPFR_ASSERTN (tern < 0 && mpfr_cmp_si_2exp (z, -3, -2) == 0); ++ ++ mpfr_clear (x); ++ mpfr_clear (y); ++ mpfr_clear (z); ++} ++ ++/* bug found by Kevin P. Rauch on 22 Oct 2007 */ ++static void ++check3 (void) ++{ ++ mpfr_t x, y, z; ++ int tern; ++ ++ mpfr_init2 (x, 32); ++ mpfr_init2 (y, 32); ++ mpfr_init2 (z, 32); ++ ++ mpfr_set_ui (x, 0xBFFFFFFFU, GMP_RNDN); /* 3221225471/2^32 */ ++ mpfr_set_ui (y, 0x80000001U, GMP_RNDN); /* 2147483649/2^32 */ ++ mpfr_set_exp (x, 0); ++ mpfr_set_exp (y, 0); ++ mpfr_set_emin (-1); ++ ++ /* the exact product is 6917529028714823679/2^64, which is rounded to ++ 3/8 = 0.375, which is smaller, thus tern < 0 */ ++ tern = mpfr_mul (z, x, y, GMP_RNDN); ++ MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); ++ ++ tern = mpfr_subnormalize (z, tern, GMP_RNDN); ++ /* since emin = -1, and EXP(z)=-1, z should be rounded to precision ++ EXP(z)-emin+1 = 1, i.e., z should be a multiple of the smallest possible ++ positive representable value with emin=-1, which is 1/4. The two ++ possible values are 1/4 and 2/4, which are at equal distance of z. ++ But since tern < 0, we should choose the largest value, i.e., 2/4. */ ++ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); ++ ++ /* here is another test for the alternate case, where z was rounded up ++ first, thus we have to round down */ ++ mpfr_set_str_binary (x, "0.11111111111010110101011011011011"); ++ mpfr_set_str_binary (y, "0.01100000000001111100000000001110"); ++ tern = mpfr_mul (z, x, y, GMP_RNDN); ++ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); ++ tern = mpfr_subnormalize (z, tern, GMP_RNDN); ++ MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 1, -2) == 0); ++ ++ /* finally the case where z was exact, which we simulate here */ ++ mpfr_set_ui_2exp (z, 3, -3, GMP_RNDN); ++ tern = mpfr_subnormalize (z, 0, GMP_RNDN); ++ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); ++ ++ mpfr_clear (x); ++ mpfr_clear (y); ++ mpfr_clear (z); ++} + + int + main (int argc, char *argv[]) +@@ -80,6 +178,8 @@ + tests_start_mpfr (); + + check1 (); ++ check2 (); ++ check3 (); + + tests_end_mpfr (); + return 0; +diff -Naurd mpfr-2.3.0-a/version.c mpfr-2.3.0-b/version.c +--- mpfr-2.3.0-a/version.c 2007-10-05 12:21:06.000000000 +0000 ++++ mpfr-2.3.0-b/version.c 2007-10-23 03:05:51.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "2.3.0-p3"; ++ return "2.3.0-p4"; + } diff --git a/mpfr.changes b/mpfr.changes index b06fabb..ba5aab1 100644 --- a/mpfr.changes +++ b/mpfr.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Wed Dec 12 14:11:58 CET 2007 - rguenther@suse.de + +- Apply bugfixes from upstream, up to patch 4. [#343720] + ------------------------------------------------------------------- Tue Oct 2 10:10:32 CEST 2007 - ro@suse.de diff --git a/mpfr.spec b/mpfr.spec index 7c0c915..830fb26 100644 --- a/mpfr.spec +++ b/mpfr.spec @@ -12,15 +12,16 @@ Name: mpfr BuildRequires: gmp-devel -License: LGPL v2 or later +License: LGPL v2.1 or later Group: Development/Libraries/C and C++ AutoReqProv: on Requires: gmp Version: 2.3.0 -Release: 3 +Release: 4 Summary: The MPFR multiple-precision floating-point library Url: http://www.mpfr.org/ Source: mpfr-%{version}.tar.bz2 +Patch: mpfr-%{version}-patches.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -76,6 +77,8 @@ PreReq: %install_info_prereq %description devel MPFR multiple-precision floating-point library development files + + Authors: -------- Guillaume Hanrot @@ -85,6 +88,7 @@ Authors: %prep %setup -q +%patch -p1 %build %configure --enable-shared --enable-thread-safe @@ -124,7 +128,10 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/libmpfr.so %{_prefix}/include/mpf2mpfr.h %{_prefix}/include/mpfr.h + %changelog +* Wed Dec 12 2007 - rguenther@suse.de +- Apply bugfixes from upstream, up to patch 4. [#343720] * Tue Oct 02 2007 - ro@suse.de - added provides mpfr to libmpfr1 package * Wed Aug 29 2007 - rguenther@suse.de