patches/mpfr/2.4.2/100-sin_cos_underflow.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jan 17 23:06:02 2010 +0100 (2010-01-17)
changeset 1740 c57458bb354d
permissions -rw-r--r--
configure: do not require hg when configuring in an hg clone

When configuring in an hg clone, we need hg to compute the version string.
It can happen that users do not have Mercurial (eg. if they got a snapshot
rather that they did a full clone). In this case, we can still run, of
course, so simply fill the version string with a sufficiently explicit
value, that does not require hg. The date is a good candidate.
     1 diff -Naurd mpfr-2.4.2-a/PATCHES mpfr-2.4.2-b/PATCHES
     2 --- mpfr-2.4.2-a/PATCHES	2009-12-07 13:37:12.000000000 +0000
     3 +++ mpfr-2.4.2-b/PATCHES	2009-12-07 13:37:12.000000000 +0000
     4 @@ -0,0 +1 @@
     5 +sin_cos_underflow
     6 diff -Naurd mpfr-2.4.2-a/VERSION mpfr-2.4.2-b/VERSION
     7 --- mpfr-2.4.2-a/VERSION	2009-11-30 02:43:08.000000000 +0000
     8 +++ mpfr-2.4.2-b/VERSION	2009-12-07 13:37:12.000000000 +0000
     9 @@ -1 +1 @@
    10 -2.4.2
    11 +2.4.2-p1
    12 diff -Naurd mpfr-2.4.2-a/mpfr.h mpfr-2.4.2-b/mpfr.h
    13 --- mpfr-2.4.2-a/mpfr.h	2009-11-30 02:43:08.000000000 +0000
    14 +++ mpfr-2.4.2-b/mpfr.h	2009-12-07 13:37:12.000000000 +0000
    15 @@ -27,7 +27,7 @@
    16  #define MPFR_VERSION_MAJOR 2
    17  #define MPFR_VERSION_MINOR 4
    18  #define MPFR_VERSION_PATCHLEVEL 2
    19 -#define MPFR_VERSION_STRING "2.4.2"
    20 +#define MPFR_VERSION_STRING "2.4.2-p1"
    21  
    22  /* Macros dealing with MPFR VERSION */
    23  #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
    24 diff -Naurd mpfr-2.4.2-a/sin_cos.c mpfr-2.4.2-b/sin_cos.c
    25 --- mpfr-2.4.2-a/sin_cos.c	2009-11-30 02:43:09.000000000 +0000
    26 +++ mpfr-2.4.2-b/sin_cos.c	2009-12-07 13:37:12.000000000 +0000
    27 @@ -82,17 +82,19 @@
    28        if (y != x)
    29          /* y and x differ, thus we can safely try to compute y first */
    30          {
    31 -          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0, rnd_mode,
    32 -                                            { inexy = _inexact;
    33 -                                              goto small_input; });
    34 +          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    35 +            y, x, -2 * expx, 2, 0, rnd_mode,
    36 +            { inexy = _inexact;
    37 +              goto small_input; });
    38            if (0)
    39              {
    40              small_input:
    41                /* we can go here only if we can round sin(x) */
    42 -              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
    43 -                                                1, 0, rnd_mode,
    44 -                                                { inexz = _inexact;
    45 -                                                  goto end; });
    46 +              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    47 +                z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
    48 +                { inexz = _inexact;
    49 +                  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
    50 +                  goto end; });
    51              }
    52  
    53            /* if we go here, one of the two MPFR_FAST_COMPUTE_IF_SMALL_INPUT
    54 @@ -101,18 +103,19 @@
    55        else /* y and x are the same variable: try to compute z first, which
    56                necessarily differs */
    57          {
    58 -          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
    59 -                                            1, 0, rnd_mode,
    60 -                                            { inexz = _inexact;
    61 -                                              goto small_input2; });
    62 +          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    63 +            z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
    64 +            { inexz = _inexact;
    65 +              goto small_input2; });
    66            if (0)
    67              {
    68              small_input2:
    69                /* we can go here only if we can round cos(x) */
    70 -              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0,
    71 -                                                rnd_mode,
    72 -                                                { inexy = _inexact;
    73 -                                                  goto end; });
    74 +              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    75 +                y, x, -2 * expx, 2, 0, rnd_mode,
    76 +                { inexy = _inexact;
    77 +                  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
    78 +                  goto end; });
    79              }
    80          }
    81        m += 2 * (-expx);
    82 @@ -207,7 +210,6 @@
    83    mpfr_clear (xr);
    84  
    85   end:
    86 -  /* FIXME: update the underflow flag if need be. */
    87    MPFR_SAVE_EXPO_FREE (expo);
    88    mpfr_check_range (y, inexy, rnd_mode);
    89    mpfr_check_range (z, inexz, rnd_mode);
    90 diff -Naurd mpfr-2.4.2-a/tests/tsin_cos.c mpfr-2.4.2-b/tests/tsin_cos.c
    91 --- mpfr-2.4.2-a/tests/tsin_cos.c	2009-11-30 02:43:08.000000000 +0000
    92 +++ mpfr-2.4.2-b/tests/tsin_cos.c	2009-12-07 13:37:12.000000000 +0000
    93 @@ -382,23 +382,56 @@
    94  consistency (void)
    95  {
    96    mpfr_t x, s1, s2, c1, c2;
    97 +  mp_exp_t emin, emax;
    98    mp_rnd_t rnd;
    99 +  unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref;
   100 +  int inex_sin, inex_cos, inex, inex_ref;
   101    int i;
   102  
   103 +  emin = mpfr_get_emin ();
   104 +  emax = mpfr_get_emax ();
   105 +
   106    for (i = 0; i <= 10000; i++)
   107      {
   108        mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8));
   109        mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2,
   110                     (mpfr_ptr) 0);
   111 -      tests_default_random (x, 256, -5, 50);
   112 -      rnd = RND_RAND ();
   113 -      mpfr_sin (s1, x, rnd);
   114 -      mpfr_cos (c1, x, rnd);
   115 -      mpfr_sin_cos (s2, c2, x, rnd);
   116 -      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)))
   117 +      if (i < 8 * GMP_RND_MAX)
   118          {
   119 -          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,\nx = ",
   120 -                  mpfr_print_rnd_mode (rnd));
   121 +          int j = i / GMP_RND_MAX;
   122 +          if (j & 1)
   123 +            mpfr_set_emin (MPFR_EMIN_MIN);
   124 +          mpfr_set_si (x, (j & 2) ? 1 : -1, GMP_RNDN);
   125 +          mpfr_set_exp (x, mpfr_get_emin ());
   126 +          rnd = (mpfr_rnd_t) (i % GMP_RND_MAX);
   127 +          flags_before = 0;
   128 +          if (j & 4)
   129 +            mpfr_set_emax (-17);
   130 +        }
   131 +      else
   132 +        {
   133 +          tests_default_random (x, 256, -5, 50);
   134 +          rnd = RND_RAND ();
   135 +          flags_before = (randlimb () & 1) ?
   136 +            (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) :
   137 +            (unsigned int) 0;
   138 +        }
   139 +      __gmpfr_flags = flags_before;
   140 +      inex_sin = mpfr_sin (s1, x, rnd);
   141 +      flags_sin = __gmpfr_flags;
   142 +      __gmpfr_flags = flags_before;
   143 +      inex_cos = mpfr_cos (c1, x, rnd);
   144 +      flags_cos = __gmpfr_flags;
   145 +      __gmpfr_flags = flags_before;
   146 +      inex = !!mpfr_sin_cos (s2, c2, x, rnd);
   147 +      flags = __gmpfr_flags;
   148 +      inex_ref = inex_sin || inex_cos;
   149 +      flags_ref = flags_sin | flags_cos;
   150 +      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) ||
   151 +          inex != inex_ref || flags != flags_ref)
   152 +        {
   153 +          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,"
   154 +                  " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i);
   155            mpfr_dump (x);
   156            printf ("s1 = ");
   157            mpfr_dump (s1);
   158 @@ -408,9 +441,16 @@
   159            mpfr_dump (c1);
   160            printf ("c2 = ");
   161            mpfr_dump (c2);
   162 +          printf ("inex_sin = %d, inex_cos = %d, inex = %d (expected %d)\n",
   163 +                  inex_sin, inex_cos, inex, inex_ref);
   164 +          printf ("flags_sin = 0x%x, flags_cos = 0x%x, "
   165 +                  "flags = 0x%x (expected 0x%x)\n",
   166 +                  flags_sin, flags_cos, flags, flags_ref);
   167            exit (1);
   168          }
   169        mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0);
   170 +      mpfr_set_emin (emin);
   171 +      mpfr_set_emax (emax);
   172      }
   173  }
   174  
   175 diff -Naurd mpfr-2.4.2-a/version.c mpfr-2.4.2-b/version.c
   176 --- mpfr-2.4.2-a/version.c	2009-11-30 02:43:08.000000000 +0000
   177 +++ mpfr-2.4.2-b/version.c	2009-12-07 13:37:12.000000000 +0000
   178 @@ -25,5 +25,5 @@
   179  const char *
   180  mpfr_get_version (void)
   181  {
   182 -  return "2.4.2";
   183 +  return "2.4.2-p1";
   184  }