Home | History | Annotate | Line # | Download | only in tests
      1      1.1  mrg /* Test file for mpfr_fma.
      2      1.1  mrg 
      3  1.1.1.6  mrg Copyright 2001-2023 Free Software Foundation, Inc.
      4  1.1.1.3  mrg Contributed by the AriC and Caramba projects, INRIA.
      5      1.1  mrg 
      6      1.1  mrg This file is part of the GNU MPFR Library.
      7      1.1  mrg 
      8      1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9      1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     10      1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     11      1.1  mrg option) any later version.
     12      1.1  mrg 
     13      1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15      1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16      1.1  mrg License for more details.
     17      1.1  mrg 
     18      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     19      1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20  1.1.1.5  mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21      1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22      1.1  mrg 
     23      1.1  mrg #include "mpfr-test.h"
     24      1.1  mrg 
     25      1.1  mrg /* When a * b is exact, the FMA is equivalent to the separate operations. */
     26      1.1  mrg static void
     27      1.1  mrg test_exact (void)
     28      1.1  mrg {
     29  1.1.1.2  mrg   const char *val[] =
     30      1.1  mrg     { "@NaN@", "-@Inf@", "-2", "-1", "-0", "0", "1", "2", "@Inf@" };
     31  1.1.1.4  mrg   int sv = numberof (val);
     32      1.1  mrg   int i, j, k;
     33      1.1  mrg   int rnd;
     34      1.1  mrg   mpfr_t a, b, c, r1, r2;
     35      1.1  mrg 
     36      1.1  mrg   mpfr_inits2 (8, a, b, c, r1, r2, (mpfr_ptr) 0);
     37      1.1  mrg 
     38      1.1  mrg   for (i = 0; i < sv; i++)
     39      1.1  mrg     for (j = 0; j < sv; j++)
     40      1.1  mrg       for (k = 0; k < sv; k++)
     41      1.1  mrg         RND_LOOP (rnd)
     42      1.1  mrg           {
     43      1.1  mrg             if (mpfr_set_str (a, val[i], 10, MPFR_RNDN) ||
     44      1.1  mrg                 mpfr_set_str (b, val[j], 10, MPFR_RNDN) ||
     45      1.1  mrg                 mpfr_set_str (c, val[k], 10, MPFR_RNDN) ||
     46      1.1  mrg                 mpfr_mul (r1, a, b, (mpfr_rnd_t) rnd) ||
     47      1.1  mrg                 mpfr_add (r1, r1, c, (mpfr_rnd_t) rnd))
     48      1.1  mrg               {
     49  1.1.1.4  mrg                 if (rnd == MPFR_RNDF)
     50  1.1.1.5  mrg                   continue;
     51  1.1.1.4  mrg                 printf ("test_exact internal error for (%d,%d,%d,%d,%s)\n",
     52  1.1.1.4  mrg                         i, j, k, rnd, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
     53      1.1  mrg                 exit (1);
     54      1.1  mrg               }
     55      1.1  mrg             if (mpfr_fma (r2, a, b, c, (mpfr_rnd_t) rnd))
     56      1.1  mrg               {
     57      1.1  mrg                 printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be exact\n",
     58      1.1  mrg                         i, j, k, rnd);
     59      1.1  mrg                 exit (1);
     60      1.1  mrg               }
     61      1.1  mrg             if (MPFR_IS_NAN (r1))
     62      1.1  mrg               {
     63      1.1  mrg                 if (MPFR_IS_NAN (r2))
     64      1.1  mrg                   continue;
     65      1.1  mrg                 printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be NaN\n",
     66      1.1  mrg                         i, j, k, rnd);
     67      1.1  mrg                 exit (1);
     68      1.1  mrg               }
     69  1.1.1.3  mrg             if (! mpfr_equal_p (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2))
     70      1.1  mrg               {
     71      1.1  mrg                 printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd);
     72      1.1  mrg                 mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN);
     73      1.1  mrg                 printf ("\n     got ");
     74      1.1  mrg                 mpfr_out_str (stdout, 10, 0, r2, MPFR_RNDN);
     75      1.1  mrg                 printf ("\n");
     76      1.1  mrg                 exit (1);
     77      1.1  mrg               }
     78      1.1  mrg           }
     79      1.1  mrg 
     80      1.1  mrg   mpfr_clears (a, b, c, r1, r2, (mpfr_ptr) 0);
     81      1.1  mrg }
     82      1.1  mrg 
     83      1.1  mrg static void
     84      1.1  mrg test_overflow1 (void)
     85      1.1  mrg {
     86      1.1  mrg   mpfr_t x, y, z, r;
     87      1.1  mrg   int inex;
     88      1.1  mrg 
     89      1.1  mrg   mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
     90      1.1  mrg   MPFR_SET_POS (x);
     91      1.1  mrg   mpfr_setmax (x, mpfr_get_emax ());  /* x = 2^emax - ulp */
     92      1.1  mrg   mpfr_set_ui (y, 2, MPFR_RNDN);       /* y = 2 */
     93      1.1  mrg   mpfr_neg (z, x, MPFR_RNDN);          /* z = -x = -(2^emax - ulp) */
     94      1.1  mrg   mpfr_clear_flags ();
     95      1.1  mrg   /* The intermediate multiplication x * y overflows, but x * y + z = x
     96      1.1  mrg      is representable. */
     97      1.1  mrg   inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
     98      1.1  mrg   if (inex || ! mpfr_equal_p (r, x))
     99      1.1  mrg     {
    100      1.1  mrg       printf ("Error in test_overflow1\nexpected ");
    101      1.1  mrg       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
    102      1.1  mrg       printf (" with inex = 0\n     got ");
    103      1.1  mrg       mpfr_out_str (stdout, 2, 0, r, MPFR_RNDN);
    104      1.1  mrg       printf (" with inex = %d\n", inex);
    105      1.1  mrg       exit (1);
    106      1.1  mrg     }
    107      1.1  mrg   if (mpfr_overflow_p ())
    108      1.1  mrg     {
    109      1.1  mrg       printf ("Error in test_overflow1: overflow flag set\n");
    110      1.1  mrg       exit (1);
    111      1.1  mrg     }
    112      1.1  mrg   mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
    113      1.1  mrg }
    114      1.1  mrg 
    115      1.1  mrg static void
    116      1.1  mrg test_overflow2 (void)
    117      1.1  mrg {
    118      1.1  mrg   mpfr_t x, y, z, r;
    119      1.1  mrg   int i, inex, rnd, err = 0;
    120      1.1  mrg 
    121      1.1  mrg   mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
    122      1.1  mrg 
    123      1.1  mrg   MPFR_SET_POS (x);
    124      1.1  mrg   mpfr_setmin (x, mpfr_get_emax ());  /* x = 0.1@emax */
    125      1.1  mrg   mpfr_set_si (y, -2, MPFR_RNDN);      /* y = -2 */
    126      1.1  mrg   /* The intermediate multiplication x * y will overflow. */
    127      1.1  mrg 
    128      1.1  mrg   for (i = -9; i <= 9; i++)
    129  1.1.1.4  mrg     RND_LOOP_NO_RNDF (rnd)
    130      1.1  mrg       {
    131      1.1  mrg         int inf, overflow;
    132      1.1  mrg 
    133      1.1  mrg         inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA;
    134      1.1  mrg         overflow = inf || i <= 0;
    135      1.1  mrg 
    136      1.1  mrg         inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), MPFR_RNDN);
    137      1.1  mrg         MPFR_ASSERTN (inex == 0);
    138      1.1  mrg 
    139      1.1  mrg         mpfr_clear_flags ();
    140      1.1  mrg         /* One has: x * y = -1@emax exactly (but not representable). */
    141      1.1  mrg         inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd);
    142      1.1  mrg         if (overflow ^ (mpfr_overflow_p () != 0))
    143      1.1  mrg           {
    144      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): wrong overflow"
    145      1.1  mrg                     " flag (should be %d)\n", i,
    146      1.1  mrg                     mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), overflow);
    147      1.1  mrg             err = 1;
    148      1.1  mrg           }
    149      1.1  mrg         if (mpfr_nanflag_p ())
    150      1.1  mrg           {
    151      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): NaN flag should"
    152      1.1  mrg                     " not be set\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    153      1.1  mrg             err = 1;
    154      1.1  mrg           }
    155      1.1  mrg         if (mpfr_nan_p (r))
    156      1.1  mrg           {
    157      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): got NaN\n",
    158      1.1  mrg                     i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    159      1.1  mrg             err = 1;
    160      1.1  mrg           }
    161  1.1.1.4  mrg         else if (MPFR_IS_POS (r))
    162      1.1  mrg           {
    163      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): wrong sign "
    164      1.1  mrg                     "(+ instead of -)\n", i,
    165      1.1  mrg                     mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    166      1.1  mrg             err = 1;
    167      1.1  mrg           }
    168      1.1  mrg         else if (inf && ! mpfr_inf_p (r))
    169      1.1  mrg           {
    170      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): expected -Inf,"
    171      1.1  mrg                     " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    172      1.1  mrg             mpfr_dump (r);
    173      1.1  mrg             err = 1;
    174      1.1  mrg           }
    175      1.1  mrg         else if (!inf && (mpfr_inf_p (r) ||
    176      1.1  mrg                           (mpfr_nextbelow (r), ! mpfr_inf_p (r))))
    177      1.1  mrg           {
    178      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): expected -MAX,"
    179      1.1  mrg                     " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    180      1.1  mrg             mpfr_dump (r);
    181      1.1  mrg             err = 1;
    182      1.1  mrg           }
    183      1.1  mrg         if (inf ? inex >= 0 : inex <= 0)
    184      1.1  mrg           {
    185      1.1  mrg             printf ("Error in test_overflow2 (i = %d, %s): wrong inexact"
    186      1.1  mrg                     " flag (got %d)\n", i,
    187      1.1  mrg                     mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex);
    188      1.1  mrg             err = 1;
    189      1.1  mrg           }
    190      1.1  mrg 
    191      1.1  mrg       }
    192      1.1  mrg 
    193      1.1  mrg   if (err)
    194      1.1  mrg     exit (1);
    195      1.1  mrg   mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
    196      1.1  mrg }
    197      1.1  mrg 
    198      1.1  mrg static void
    199  1.1.1.5  mrg test_overflow3 (void)
    200  1.1.1.5  mrg {
    201  1.1.1.5  mrg   mpfr_t x, y, z, r;
    202  1.1.1.5  mrg   int inex;
    203  1.1.1.5  mrg   mpfr_prec_t p = 8;
    204  1.1.1.5  mrg   mpfr_flags_t ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT, flags;
    205  1.1.1.5  mrg   int i, j, k;
    206  1.1.1.5  mrg   unsigned int neg;
    207  1.1.1.5  mrg 
    208  1.1.1.5  mrg   mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
    209  1.1.1.5  mrg   for (i = 0; i < 2; i++)
    210  1.1.1.5  mrg     {
    211  1.1.1.5  mrg       mpfr_init2 (r, 2 * p + i);
    212  1.1.1.5  mrg       mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
    213  1.1.1.5  mrg       mpfr_set_ui (y, 2, MPFR_RNDN);       /* y = 2 */
    214  1.1.1.5  mrg       for (j = 1; j <= 2; j++)
    215  1.1.1.5  mrg         for (k = 0; k <= 1; k++)
    216  1.1.1.5  mrg           {
    217  1.1.1.5  mrg             mpfr_set_si_2exp (z, -1, mpfr_get_emax () - mpfr_get_prec (r) - j,
    218  1.1.1.5  mrg                               MPFR_RNDN);
    219  1.1.1.5  mrg             if (k)
    220  1.1.1.5  mrg               mpfr_nextabove (z);
    221  1.1.1.5  mrg             for (neg = 0; neg <= 3; neg++)
    222  1.1.1.5  mrg               {
    223  1.1.1.5  mrg                 mpfr_clear_flags ();
    224  1.1.1.5  mrg                 /* (The following applies for neg = 0 or 2, all the signs
    225  1.1.1.5  mrg                    need to be reversed for neg = 1 or 3.)
    226  1.1.1.5  mrg                    We have x*y = 2^emax and
    227  1.1.1.5  mrg                    z = - 2^(emax-2p-i-j) * (1-k*2^(-p)), thus
    228  1.1.1.5  mrg                    x*y+z = 2^emax - 2^(emax-2p-i-j) + k*2^(emax-3p-i-j)
    229  1.1.1.5  mrg                    should overflow. Indeed it is >= the midpoint of
    230  1.1.1.5  mrg                    2^emax - 2^(emax-2p-i) and 2^emax, the midpoint
    231  1.1.1.5  mrg                    being obtained for j = 1 and k = 0. */
    232  1.1.1.5  mrg                 inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
    233  1.1.1.5  mrg                 flags = __gmpfr_flags;
    234  1.1.1.5  mrg                 if (! mpfr_inf_p (r) || flags != ex_flags ||
    235  1.1.1.5  mrg                     ((neg & 1) == 0 ?
    236  1.1.1.5  mrg                      (inex <= 0 || MPFR_IS_NEG (r)) :
    237  1.1.1.5  mrg                      (inex >= 0 || MPFR_IS_POS (r))))
    238  1.1.1.5  mrg                   {
    239  1.1.1.5  mrg                     printf ("Error in test_overflow3 for "
    240  1.1.1.5  mrg                             "i=%d j=%d k=%d neg=%u\n", i, j, k, neg);
    241  1.1.1.5  mrg                     printf ("Expected %c@Inf@\n  with inex %c 0 and flags:",
    242  1.1.1.5  mrg                             (neg & 1) == 0 ? '+' : '-',
    243  1.1.1.5  mrg                             (neg & 1) == 0 ? '>' : '<');
    244  1.1.1.5  mrg                     flags_out (ex_flags);
    245  1.1.1.5  mrg                     printf ("Got      ");
    246  1.1.1.5  mrg                     mpfr_dump (r);
    247  1.1.1.5  mrg                     printf ("  with inex = %d and flags:", inex);
    248  1.1.1.5  mrg                     flags_out (flags);
    249  1.1.1.5  mrg                     exit (1);
    250  1.1.1.5  mrg                   }
    251  1.1.1.5  mrg                 if (neg == 0 || neg == 2)
    252  1.1.1.5  mrg                   mpfr_neg (x, x, MPFR_RNDN);
    253  1.1.1.5  mrg                 if (neg == 1 || neg == 3)
    254  1.1.1.5  mrg                   mpfr_neg (y, y, MPFR_RNDN);
    255  1.1.1.5  mrg                 mpfr_neg (z, z, MPFR_RNDN);
    256  1.1.1.5  mrg               }  /* neg */
    257  1.1.1.5  mrg           }  /* k */
    258  1.1.1.5  mrg       mpfr_clear (r);
    259  1.1.1.5  mrg     }  /* i */
    260  1.1.1.5  mrg   mpfr_clears (x, y, z, (mpfr_ptr) 0);
    261  1.1.1.5  mrg }
    262  1.1.1.5  mrg 
    263  1.1.1.5  mrg static void
    264  1.1.1.5  mrg test_overflow4 (void)
    265  1.1.1.5  mrg {
    266  1.1.1.5  mrg   mpfr_t x, y, z, r1, r2;
    267  1.1.1.5  mrg   mpfr_exp_t emax, e;
    268  1.1.1.5  mrg   mpfr_prec_t px;
    269  1.1.1.5  mrg   mpfr_flags_t flags1, flags2;
    270  1.1.1.5  mrg   int inex1, inex2;
    271  1.1.1.5  mrg   int ei, i, j;
    272  1.1.1.5  mrg   int below;
    273  1.1.1.5  mrg   unsigned int neg;
    274  1.1.1.5  mrg 
    275  1.1.1.5  mrg   emax = mpfr_get_emax ();
    276  1.1.1.5  mrg 
    277  1.1.1.5  mrg   mpfr_init2 (y, MPFR_PREC_MIN);
    278  1.1.1.5  mrg   mpfr_set_ui (y, 2, MPFR_RNDN);  /* y = 2 */
    279  1.1.1.5  mrg 
    280  1.1.1.5  mrg   mpfr_init2 (z, 8);
    281  1.1.1.5  mrg 
    282  1.1.1.5  mrg   for (px = 17; px < 256; px *= 2)
    283  1.1.1.5  mrg     {
    284  1.1.1.5  mrg       mpfr_init2 (x, px);
    285  1.1.1.5  mrg       mpfr_inits2 (px - 8, r1, r2, (mpfr_ptr) 0);
    286  1.1.1.5  mrg       for (ei = 0; ei <= 1; ei++)
    287  1.1.1.5  mrg         {
    288  1.1.1.5  mrg           e = ei ? emax : 0;
    289  1.1.1.5  mrg           mpfr_set_ui_2exp (x, 1, e - 1, MPFR_RNDN);
    290  1.1.1.5  mrg           mpfr_nextabove (x);  /* x = 2^(e - 1) + 2^(e - px) */
    291  1.1.1.5  mrg           /* x*y = 2^e + 2^(e - px + 1), which internally overflows
    292  1.1.1.5  mrg              when e = emax. */
    293  1.1.1.5  mrg           for (i = -4; i <= 4; i++)
    294  1.1.1.5  mrg             for (j = 2; j <= 3; j++)
    295  1.1.1.5  mrg               {
    296  1.1.1.5  mrg                 mpfr_set_si_2exp (z, -j, e - px + i, MPFR_RNDN);
    297  1.1.1.5  mrg                 /* If |z| <= 2^(e - px + 1), then x*y + z >= 2^e and
    298  1.1.1.5  mrg                    RZ(x*y + z) = 2^e with an unbounded exponent range.
    299  1.1.1.5  mrg                    If |z| > 2^(e - px + 1), then RZ(x*y + z) is the
    300  1.1.1.5  mrg                    predecessor of 2^e (since |z| < ulp(r)/2); this
    301  1.1.1.5  mrg                    occurs when i > 0 and when i = 0 and j > 2 */
    302  1.1.1.5  mrg                 mpfr_set_ui_2exp (r1, 1, e - 1, MPFR_RNDN);
    303  1.1.1.5  mrg                 below = i > 0 || (i == 0 && j > 2);
    304  1.1.1.5  mrg                 if (below)
    305  1.1.1.5  mrg                   mpfr_nextbelow (r1);
    306  1.1.1.5  mrg                 mpfr_clear_flags ();
    307  1.1.1.5  mrg                 inex1 = mpfr_mul_2ui (r1, r1, 1, MPFR_RNDZ);
    308  1.1.1.5  mrg                 if (below || e < emax)
    309  1.1.1.5  mrg                   {
    310  1.1.1.5  mrg                     inex1 = i == 0 && j == 2 ? 0 : -1;
    311  1.1.1.5  mrg                     flags1 = inex1 ? MPFR_FLAGS_INEXACT : 0;
    312  1.1.1.5  mrg                   }
    313  1.1.1.5  mrg                 else
    314  1.1.1.5  mrg                   {
    315  1.1.1.5  mrg                     MPFR_ASSERTN (inex1 < 0);
    316  1.1.1.5  mrg                     flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
    317  1.1.1.5  mrg                     MPFR_ASSERTN (flags1 == __gmpfr_flags);
    318  1.1.1.5  mrg                   }
    319  1.1.1.5  mrg                 for (neg = 0; neg <= 3; neg++)
    320  1.1.1.5  mrg                   {
    321  1.1.1.5  mrg                     mpfr_clear_flags ();
    322  1.1.1.5  mrg                     inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDZ);
    323  1.1.1.5  mrg                     flags2 = __gmpfr_flags;
    324  1.1.1.5  mrg                     if (! (mpfr_equal_p (r1, r2) &&
    325  1.1.1.5  mrg                            SAME_SIGN (inex1, inex2) &&
    326  1.1.1.5  mrg                            flags1 == flags2))
    327  1.1.1.5  mrg                       {
    328  1.1.1.5  mrg                         printf ("Error in test_overflow4 for "
    329  1.1.1.5  mrg                                 "px=%d ei=%d i=%d j=%d neg=%u\n",
    330  1.1.1.5  mrg                                 (int) px, ei, i, j, neg);
    331  1.1.1.5  mrg                         printf ("Expected ");
    332  1.1.1.5  mrg                         mpfr_dump (r1);
    333  1.1.1.5  mrg                         printf ("with inex = %d and flags:", inex1);
    334  1.1.1.5  mrg                         flags_out (flags1);
    335  1.1.1.5  mrg                         printf ("Got      ");
    336  1.1.1.5  mrg                         mpfr_dump (r2);
    337  1.1.1.5  mrg                         printf ("with inex = %d and flags:", inex2);
    338  1.1.1.5  mrg                         flags_out (flags2);
    339  1.1.1.5  mrg                         exit (1);
    340  1.1.1.5  mrg                       }
    341  1.1.1.5  mrg                     if (neg == 0 || neg == 2)
    342  1.1.1.5  mrg                       mpfr_neg (x, x, MPFR_RNDN);
    343  1.1.1.5  mrg                     if (neg == 1 || neg == 3)
    344  1.1.1.5  mrg                       mpfr_neg (y, y, MPFR_RNDN);
    345  1.1.1.5  mrg                     mpfr_neg (z, z, MPFR_RNDN);
    346  1.1.1.5  mrg                     mpfr_neg (r1, r1, MPFR_RNDN);
    347  1.1.1.5  mrg                     inex1 = - inex1;
    348  1.1.1.5  mrg                   }
    349  1.1.1.5  mrg               }
    350  1.1.1.5  mrg         }
    351  1.1.1.5  mrg       mpfr_clears (x, r1, r2, (mpfr_ptr) 0);
    352  1.1.1.5  mrg     }
    353  1.1.1.5  mrg 
    354  1.1.1.5  mrg   mpfr_clears (y, z, (mpfr_ptr) 0);
    355  1.1.1.5  mrg }
    356  1.1.1.5  mrg 
    357  1.1.1.5  mrg static void
    358  1.1.1.5  mrg test_overflow5 (void)
    359  1.1.1.5  mrg {
    360  1.1.1.5  mrg   mpfr_t x, y, z, r1, r2;
    361  1.1.1.5  mrg   mpfr_exp_t emax;
    362  1.1.1.5  mrg   int inex1, inex2;
    363  1.1.1.5  mrg   int i, rnd;
    364  1.1.1.5  mrg   unsigned int neg, negr;
    365  1.1.1.5  mrg 
    366  1.1.1.5  mrg   emax = mpfr_get_emax ();
    367  1.1.1.5  mrg 
    368  1.1.1.5  mrg   mpfr_init2 (x, 123);
    369  1.1.1.5  mrg   mpfr_init2 (y, 45);
    370  1.1.1.5  mrg   mpfr_init2 (z, 67);
    371  1.1.1.5  mrg   mpfr_inits2 (89, r1, r2, (mpfr_ptr) 0);
    372  1.1.1.5  mrg 
    373  1.1.1.5  mrg   mpfr_set_ui_2exp (x, 1, emax - 1, MPFR_RNDN);
    374  1.1.1.5  mrg 
    375  1.1.1.5  mrg   for (i = 3; i <= 17; i++)
    376  1.1.1.5  mrg     {
    377  1.1.1.5  mrg       mpfr_set_ui (y, i, MPFR_RNDN);
    378  1.1.1.5  mrg       mpfr_set_ui_2exp (z, 1, emax - 1, MPFR_RNDN);
    379  1.1.1.5  mrg       for (neg = 0; neg < 8; neg++)
    380  1.1.1.5  mrg         {
    381  1.1.1.5  mrg           mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
    382  1.1.1.5  mrg           mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
    383  1.1.1.5  mrg           mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
    384  1.1.1.5  mrg 
    385  1.1.1.5  mrg           /* |x*y + z| = (i +/- 1) * 2^(emax - 1) >= 2^emax (overflow)
    386  1.1.1.5  mrg              and x*y + z has the same sign as x*y. */
    387  1.1.1.5  mrg           negr = (neg ^ (neg >> 1)) & 1;
    388  1.1.1.5  mrg 
    389  1.1.1.5  mrg           RND_LOOP (rnd)
    390  1.1.1.5  mrg             {
    391  1.1.1.5  mrg               mpfr_set_inf (r1, 1);
    392  1.1.1.5  mrg               if (MPFR_IS_LIKE_RNDZ ((mpfr_rnd_t) rnd, negr))
    393  1.1.1.5  mrg                 {
    394  1.1.1.5  mrg                   mpfr_nextbelow (r1);
    395  1.1.1.5  mrg                   inex1 = -1;
    396  1.1.1.5  mrg                 }
    397  1.1.1.5  mrg               else
    398  1.1.1.5  mrg                 inex1 = 1;
    399  1.1.1.5  mrg 
    400  1.1.1.5  mrg               if (negr)
    401  1.1.1.5  mrg                 {
    402  1.1.1.5  mrg                   mpfr_neg (r1, r1, MPFR_RNDN);
    403  1.1.1.5  mrg                   inex1 = - inex1;
    404  1.1.1.5  mrg                 }
    405  1.1.1.5  mrg 
    406  1.1.1.5  mrg               mpfr_clear_flags ();
    407  1.1.1.5  mrg               inex2 = mpfr_fma (r2, x, y, z, (mpfr_rnd_t) rnd);
    408  1.1.1.5  mrg               MPFR_ASSERTN (__gmpfr_flags ==
    409  1.1.1.5  mrg                             (MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW));
    410  1.1.1.5  mrg 
    411  1.1.1.5  mrg               if (! (mpfr_equal_p (r1, r2) && SAME_SIGN (inex1, inex2)))
    412  1.1.1.5  mrg                 {
    413  1.1.1.5  mrg                   printf ("Error in test_overflow5 for i=%d neg=%u %s\n",
    414  1.1.1.5  mrg                           i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    415  1.1.1.5  mrg                   printf ("Expected ");
    416  1.1.1.5  mrg                   mpfr_dump (r1);
    417  1.1.1.5  mrg                   printf ("with inex = %d\n", inex1);
    418  1.1.1.5  mrg                   printf ("Got      ");
    419  1.1.1.5  mrg                   mpfr_dump (r2);
    420  1.1.1.5  mrg                   printf ("with inex = %d\n", inex2);
    421  1.1.1.5  mrg                   exit (1);
    422  1.1.1.5  mrg                 }
    423  1.1.1.5  mrg             }  /* rnd */
    424  1.1.1.5  mrg         }  /* neg */
    425  1.1.1.5  mrg     }  /* i */
    426  1.1.1.5  mrg 
    427  1.1.1.5  mrg   mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
    428  1.1.1.5  mrg }
    429  1.1.1.5  mrg 
    430  1.1.1.5  mrg static void
    431      1.1  mrg test_underflow1 (void)
    432      1.1  mrg {
    433      1.1  mrg   mpfr_t x, y, z, r;
    434      1.1  mrg   int inex, signy, signz, rnd, err = 0;
    435      1.1  mrg 
    436      1.1  mrg   mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
    437      1.1  mrg 
    438      1.1  mrg   MPFR_SET_POS (x);
    439      1.1  mrg   mpfr_setmin (x, mpfr_get_emin ());  /* x = 0.1@emin */
    440      1.1  mrg 
    441      1.1  mrg   for (signy = -1; signy <= 1; signy += 2)
    442      1.1  mrg     {
    443      1.1  mrg       mpfr_set_si_2exp (y, signy, -1, MPFR_RNDN);  /* |y| = 1/2 */
    444      1.1  mrg       for (signz = -3; signz <= 3; signz += 2)
    445      1.1  mrg         {
    446      1.1  mrg           RND_LOOP (rnd)
    447      1.1  mrg             {
    448      1.1  mrg               mpfr_set_si (z, signz, MPFR_RNDN);
    449      1.1  mrg               if (ABS (signz) != 1)
    450      1.1  mrg                 mpfr_setmax (z, mpfr_get_emax ());
    451      1.1  mrg               /* |z| = 1 or 2^emax - ulp */
    452      1.1  mrg               mpfr_clear_flags ();
    453      1.1  mrg               inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd);
    454  1.1.1.4  mrg #define STRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n  "
    455      1.1  mrg               if (mpfr_nanflag_p ())
    456      1.1  mrg                 {
    457  1.1.1.4  mrg                   printf (STRTU1 "NaN flag is set\n", signy, signz,
    458      1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    459      1.1  mrg                   err = 1;
    460      1.1  mrg                 }
    461      1.1  mrg               if (signy < 0 && MPFR_IS_LIKE_RNDD(rnd, signz))
    462      1.1  mrg                 mpfr_nextbelow (z);
    463      1.1  mrg               if (signy > 0 && MPFR_IS_LIKE_RNDU(rnd, signz))
    464      1.1  mrg                 mpfr_nextabove (z);
    465      1.1  mrg               if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0))
    466      1.1  mrg                 {
    467  1.1.1.4  mrg                   printf (STRTU1 "wrong overflow flag\n", signy, signz,
    468      1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    469      1.1  mrg                   err = 1;
    470      1.1  mrg                 }
    471      1.1  mrg               if (mpfr_underflow_p ())
    472      1.1  mrg                 {
    473  1.1.1.4  mrg                   printf (STRTU1 "underflow flag is set\n", signy, signz,
    474      1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    475      1.1  mrg                   err = 1;
    476      1.1  mrg                 }
    477      1.1  mrg               if (! mpfr_equal_p (r, z))
    478      1.1  mrg                 {
    479  1.1.1.4  mrg                   printf (STRTU1 "got        ", signy, signz,
    480      1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    481  1.1.1.4  mrg                   mpfr_dump (r);
    482  1.1.1.4  mrg                   printf ("  instead of ");
    483  1.1.1.4  mrg                   mpfr_dump (z);
    484      1.1  mrg                   err = 1;
    485      1.1  mrg                 }
    486      1.1  mrg               if (inex >= 0 && (rnd == MPFR_RNDD ||
    487      1.1  mrg                                 (rnd == MPFR_RNDZ && signz > 0) ||
    488      1.1  mrg                                 (rnd == MPFR_RNDN && signy > 0)))
    489      1.1  mrg                 {
    490  1.1.1.4  mrg                   printf (STRTU1 "ternary value = %d instead of < 0\n",
    491      1.1  mrg                           signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
    492      1.1  mrg                           inex);
    493      1.1  mrg                   err = 1;
    494      1.1  mrg                 }
    495      1.1  mrg               if (inex <= 0 && (rnd == MPFR_RNDU ||
    496      1.1  mrg                                 (rnd == MPFR_RNDZ && signz < 0) ||
    497      1.1  mrg                                 (rnd == MPFR_RNDN && signy < 0)))
    498      1.1  mrg                 {
    499  1.1.1.4  mrg                   printf (STRTU1 "ternary value = %d instead of > 0\n",
    500      1.1  mrg                           signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
    501      1.1  mrg                           inex);
    502      1.1  mrg                   err = 1;
    503      1.1  mrg                 }
    504      1.1  mrg             }
    505      1.1  mrg         }
    506      1.1  mrg     }
    507      1.1  mrg 
    508      1.1  mrg   if (err)
    509      1.1  mrg     exit (1);
    510      1.1  mrg   mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
    511      1.1  mrg }
    512      1.1  mrg 
    513      1.1  mrg static void
    514      1.1  mrg test_underflow2 (void)
    515      1.1  mrg {
    516  1.1.1.5  mrg   mpfr_t x, y, z, r1, r2;
    517  1.1.1.5  mrg   int e, b, i, prec = 32, pz, inex;
    518  1.1.1.5  mrg   unsigned int neg;
    519      1.1  mrg 
    520  1.1.1.5  mrg   mpfr_init2 (x, MPFR_PREC_MIN);
    521  1.1.1.5  mrg   mpfr_inits2 (prec, y, z, r1, r2, (mpfr_ptr) 0);
    522      1.1  mrg 
    523  1.1.1.5  mrg   mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
    524  1.1.1.5  mrg   /* x = 2^(emin-1) */
    525      1.1  mrg 
    526  1.1.1.5  mrg   for (e = -1; e <= prec + 2; e++)
    527      1.1  mrg     {
    528  1.1.1.5  mrg       mpfr_set (z, x, MPFR_RNDN);
    529  1.1.1.5  mrg       /* z = x = 2^(emin+e) */
    530  1.1.1.5  mrg       for (b = 0; b <= 1; b++)
    531      1.1  mrg         {
    532  1.1.1.5  mrg           for (pz = prec - 4 * (b == 0); pz <= prec + 4; pz++)
    533      1.1  mrg             {
    534  1.1.1.5  mrg               inex = mpfr_prec_round (z, pz, MPFR_RNDZ);
    535  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    536  1.1.1.5  mrg               for (i = 15; i <= 17; i++)
    537  1.1.1.5  mrg                 {
    538  1.1.1.5  mrg                   mpfr_flags_t flags1, flags2;
    539  1.1.1.5  mrg                   int inex1, inex2;
    540      1.1  mrg 
    541  1.1.1.5  mrg                   mpfr_set_si_2exp (y, i, -4 - prec, MPFR_RNDN);
    542  1.1.1.5  mrg 
    543  1.1.1.5  mrg                   /*      <--- r --->
    544  1.1.1.5  mrg                    *  z = 1.000...00b   with b = 0 or 1
    545  1.1.1.5  mrg                    * xy =            01111  (i = 15)
    546  1.1.1.5  mrg                    *   or            10000  (i = 16)
    547  1.1.1.5  mrg                    *   or            10001  (i = 17)
    548  1.1.1.5  mrg                    *
    549  1.1.1.5  mrg                    * x, y, and z will be modified to test the different sign
    550  1.1.1.5  mrg                    * combinations. In the case b = 0 (i.e. |z| is a power of
    551  1.1.1.5  mrg                    * 2) and x*y has a different sign from z, then y will be
    552  1.1.1.5  mrg                    * divided by 2, so that i = 16 corresponds to a midpoint.
    553  1.1.1.5  mrg                    */
    554  1.1.1.5  mrg 
    555  1.1.1.5  mrg                   for (neg = 0; neg < 8; neg++)
    556  1.1.1.5  mrg                     {
    557  1.1.1.5  mrg                       int xyneg, prev_binade;
    558  1.1.1.5  mrg 
    559  1.1.1.5  mrg                       mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
    560  1.1.1.5  mrg                       mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
    561  1.1.1.5  mrg                       mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
    562  1.1.1.5  mrg 
    563  1.1.1.5  mrg                       xyneg = (neg ^ (neg >> 1)) & 1;  /* true iff x*y < 0 */
    564  1.1.1.5  mrg 
    565  1.1.1.5  mrg                       /* If a change of binade occurs by adding x*y to z
    566  1.1.1.5  mrg                          exactly, then take into account the fact that the
    567  1.1.1.5  mrg                          midpoint has a different exponent. */
    568  1.1.1.5  mrg                       prev_binade = b == 0 && (xyneg ^ MPFR_IS_NEG (z));
    569  1.1.1.5  mrg                       if (prev_binade)
    570  1.1.1.5  mrg                         mpfr_div_2ui (y, y, 1, MPFR_RNDN);
    571  1.1.1.5  mrg 
    572  1.1.1.5  mrg                       mpfr_set (r1, z, MPFR_RNDN);
    573  1.1.1.5  mrg                       flags1 = MPFR_FLAGS_INEXACT;
    574  1.1.1.5  mrg 
    575  1.1.1.5  mrg                       if (e == -1 && i == 17 && b == 0 &&
    576  1.1.1.5  mrg                           (xyneg ^ (neg >> 2)) != 0)
    577  1.1.1.5  mrg                         {
    578  1.1.1.5  mrg                           /* Special underflow case. */
    579  1.1.1.5  mrg                           flags1 |= MPFR_FLAGS_UNDERFLOW;
    580  1.1.1.5  mrg                           inex1 = xyneg ? 1 : -1;
    581  1.1.1.5  mrg                         }
    582  1.1.1.5  mrg                       else if (i == 15 || (i == 16 && b == 0))
    583  1.1.1.5  mrg                         {
    584  1.1.1.5  mrg                           /* round toward z */
    585  1.1.1.5  mrg                           inex1 = xyneg ? 1 : -1;
    586  1.1.1.5  mrg                         }
    587  1.1.1.5  mrg                       else if (xyneg)
    588  1.1.1.5  mrg                         {
    589  1.1.1.5  mrg                           /* round away from z, with x*y < 0 */
    590  1.1.1.5  mrg                           mpfr_nextbelow (r1);
    591  1.1.1.5  mrg                           inex1 = -1;
    592  1.1.1.5  mrg                         }
    593  1.1.1.5  mrg                       else
    594  1.1.1.5  mrg                         {
    595  1.1.1.5  mrg                           /* round away from z, with x*y > 0 */
    596  1.1.1.5  mrg                           mpfr_nextabove (r1);
    597  1.1.1.5  mrg                           inex1 = 1;
    598  1.1.1.5  mrg                         }
    599  1.1.1.5  mrg 
    600  1.1.1.5  mrg                       mpfr_clear_flags ();
    601  1.1.1.5  mrg                       inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDN);
    602  1.1.1.5  mrg                       flags2 = __gmpfr_flags;
    603  1.1.1.5  mrg 
    604  1.1.1.5  mrg                       if (! (mpfr_equal_p (r1, r2) &&
    605  1.1.1.5  mrg                              SAME_SIGN (inex1, inex2) &&
    606  1.1.1.5  mrg                              flags1 == flags2))
    607  1.1.1.5  mrg                         {
    608  1.1.1.5  mrg                           printf ("Error in test_underflow2 for "
    609  1.1.1.5  mrg                                   "e=%d b=%d pz=%d i=%d neg=%u\n",
    610  1.1.1.5  mrg                                   e, b, pz, i, neg);
    611  1.1.1.5  mrg                           printf ("Expected ");
    612  1.1.1.5  mrg                           mpfr_dump (r1);
    613  1.1.1.5  mrg                           printf ("with inex = %d and flags:", inex1);
    614  1.1.1.5  mrg                           flags_out (flags1);
    615  1.1.1.5  mrg                           printf ("Got      ");
    616  1.1.1.5  mrg                           mpfr_dump (r2);
    617  1.1.1.5  mrg                           printf ("with inex = %d and flags:", inex2);
    618  1.1.1.5  mrg                           flags_out (flags2);
    619  1.1.1.5  mrg                           exit (1);
    620  1.1.1.5  mrg                         }
    621  1.1.1.5  mrg 
    622  1.1.1.5  mrg                       /* Restore y. */
    623  1.1.1.5  mrg                       if (prev_binade)
    624  1.1.1.5  mrg                         mpfr_mul_2ui (y, y, 1, MPFR_RNDN);
    625  1.1.1.5  mrg                     }  /* neg */
    626  1.1.1.5  mrg                 }  /* i */
    627  1.1.1.5  mrg             }  /* pz */
    628  1.1.1.5  mrg 
    629  1.1.1.5  mrg           inex = mpfr_prec_round (z, prec, MPFR_RNDZ);
    630  1.1.1.5  mrg           MPFR_ASSERTN (inex == 0);
    631  1.1.1.5  mrg           MPFR_SET_POS (z);
    632  1.1.1.5  mrg           mpfr_nextabove (z);
    633  1.1.1.5  mrg         }  /* b */
    634  1.1.1.5  mrg       mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
    635  1.1.1.5  mrg     }  /* e */
    636  1.1.1.5  mrg 
    637  1.1.1.5  mrg   mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
    638      1.1  mrg }
    639      1.1  mrg 
    640      1.1  mrg static void
    641  1.1.1.3  mrg test_underflow3 (int n)
    642  1.1.1.3  mrg {
    643  1.1.1.3  mrg   mpfr_t x, y, z, t1, t2;
    644  1.1.1.3  mrg   int sign, k, s, rnd, inex1, inex2;
    645  1.1.1.3  mrg   mpfr_exp_t e;
    646  1.1.1.4  mrg   mpfr_flags_t flags1, flags2;
    647  1.1.1.3  mrg 
    648  1.1.1.3  mrg   mpfr_inits2 (4, x, z, t1, t2, (mpfr_ptr) 0);
    649  1.1.1.3  mrg   mpfr_init2 (y, 6);
    650  1.1.1.3  mrg 
    651  1.1.1.3  mrg   e = mpfr_get_emin () - 1;
    652  1.1.1.3  mrg 
    653  1.1.1.3  mrg   for (sign = 1; sign >= -1; sign -= 2)
    654  1.1.1.3  mrg     for (k = 1; k <= 7; k++)
    655  1.1.1.3  mrg       for (s = -1; s <= 1; s++)
    656  1.1.1.3  mrg         {
    657  1.1.1.3  mrg           mpfr_set_si_2exp (x, sign, e, MPFR_RNDN);
    658  1.1.1.3  mrg           mpfr_set_si_2exp (y, 8*k+s, -6, MPFR_RNDN);
    659  1.1.1.3  mrg           mpfr_neg (z, x, MPFR_RNDN);
    660  1.1.1.3  mrg           /* x = sign * 2^(emin-1)
    661  1.1.1.3  mrg              y = (8 * k + s) * 2^(-6) = k / 8 + s * 2^(-6)
    662  1.1.1.3  mrg              z = -x = -sign * 2^(emin-1)
    663  1.1.1.3  mrg              FMA(x,y,z) = sign * ((k-8) * 2^(emin-4) + s * 2^(emin-7)) exactly.
    664  1.1.1.3  mrg              Note: The purpose of the s * 2^(emin-7) term is to yield
    665  1.1.1.3  mrg              double rounding when scaling for k = 4, s != 0, MPFR_RNDN. */
    666  1.1.1.3  mrg 
    667  1.1.1.5  mrg           RND_LOOP_NO_RNDF (rnd)
    668  1.1.1.3  mrg             {
    669  1.1.1.3  mrg               mpfr_clear_flags ();
    670  1.1.1.3  mrg               inex1 = mpfr_set_si_2exp (t1, sign * (8*k+s-64), e-6,
    671  1.1.1.3  mrg                                         (mpfr_rnd_t) rnd);
    672  1.1.1.3  mrg               flags1 = __gmpfr_flags;
    673  1.1.1.3  mrg 
    674  1.1.1.3  mrg               mpfr_clear_flags ();
    675  1.1.1.3  mrg               inex2 = mpfr_fma (t2, x, y, z, (mpfr_rnd_t) rnd);
    676  1.1.1.3  mrg               flags2 = __gmpfr_flags;
    677  1.1.1.3  mrg 
    678  1.1.1.3  mrg               if (! (mpfr_equal_p (t1, t2) &&
    679  1.1.1.3  mrg                      SAME_SIGN (inex1, inex2) &&
    680  1.1.1.3  mrg                      flags1 == flags2))
    681  1.1.1.3  mrg                 {
    682  1.1.1.3  mrg                   printf ("Error in test_underflow3, n = %d, sign = %d,"
    683  1.1.1.3  mrg                           " k = %d, s = %d, %s\n", n, sign, k, s,
    684  1.1.1.3  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    685  1.1.1.3  mrg                   printf ("Expected ");
    686  1.1.1.3  mrg                   mpfr_dump (t1);
    687  1.1.1.3  mrg                   printf ("  with inex ~ %d, flags =", inex1);
    688  1.1.1.3  mrg                   flags_out (flags1);
    689  1.1.1.3  mrg                   printf ("Got      ");
    690  1.1.1.3  mrg                   mpfr_dump (t2);
    691  1.1.1.3  mrg                   printf ("  with inex ~ %d, flags =", inex2);
    692  1.1.1.3  mrg                   flags_out (flags2);
    693  1.1.1.3  mrg                   exit (1);
    694  1.1.1.3  mrg                 }
    695  1.1.1.3  mrg             }
    696  1.1.1.3  mrg         }
    697  1.1.1.3  mrg 
    698  1.1.1.3  mrg   mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0);
    699  1.1.1.3  mrg }
    700  1.1.1.3  mrg 
    701  1.1.1.5  mrg /* Test s = x*y + z with PREC(z) > PREC(s) + 1, x*y underflows, where
    702  1.1.1.5  mrg    z + x*y and z + sign(x*y) * 2^(emin-1) do not give the same result.
    703  1.1.1.5  mrg      x = 2^emin
    704  1.1.1.5  mrg      y = 2^(-8)
    705  1.1.1.5  mrg      z = 2^emin * (2^PREC(s) + k - 2^(-1))
    706  1.1.1.5  mrg    with k = 3 for MPFR_RNDN and k = 2 for the directed rounding modes.
    707  1.1.1.5  mrg    Also test the opposite versions with neg != 0.
    708  1.1.1.5  mrg */
    709  1.1.1.5  mrg static void
    710  1.1.1.5  mrg test_underflow4 (void)
    711  1.1.1.5  mrg {
    712  1.1.1.5  mrg   mpfr_t x, y, z, s1, s2;
    713  1.1.1.5  mrg   mpfr_prec_t ps = 32;
    714  1.1.1.5  mrg   int inex, rnd;
    715  1.1.1.5  mrg 
    716  1.1.1.5  mrg   mpfr_inits2 (MPFR_PREC_MIN, x, y, (mpfr_ptr) 0);
    717  1.1.1.5  mrg   mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
    718  1.1.1.5  mrg   mpfr_init2 (z, ps + 2);
    719  1.1.1.5  mrg 
    720  1.1.1.5  mrg   inex = mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN);
    721  1.1.1.5  mrg   MPFR_ASSERTN (inex == 0);
    722  1.1.1.5  mrg   inex = mpfr_set_si_2exp (y, 1, -8, MPFR_RNDN);
    723  1.1.1.5  mrg   MPFR_ASSERTN (inex == 0);
    724  1.1.1.5  mrg 
    725  1.1.1.5  mrg   RND_LOOP_NO_RNDF (rnd)
    726  1.1.1.5  mrg     {
    727  1.1.1.5  mrg       mpfr_flags_t flags1, flags2;
    728  1.1.1.5  mrg       int inex1, inex2;
    729  1.1.1.5  mrg       unsigned int neg;
    730  1.1.1.5  mrg 
    731  1.1.1.5  mrg       inex = mpfr_set_si_2exp (z, 1 << 1, ps, MPFR_RNDN);
    732  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    733  1.1.1.5  mrg       inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
    734  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    735  1.1.1.5  mrg       inex = mpfr_div_2ui (z, z, 1, MPFR_RNDN);
    736  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    737  1.1.1.5  mrg       inex = mpfr_add_ui (z, z, rnd == MPFR_RNDN ? 3 : 2, MPFR_RNDN);
    738  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    739  1.1.1.5  mrg       inex = mpfr_mul (z, z, x, MPFR_RNDN);
    740  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    741  1.1.1.5  mrg 
    742  1.1.1.5  mrg       for (neg = 0; neg <= 3; neg++)
    743  1.1.1.5  mrg         {
    744  1.1.1.5  mrg           inex1 = mpfr_set (s1, z, (mpfr_rnd_t) rnd);
    745  1.1.1.5  mrg           flags1 = MPFR_FLAGS_INEXACT;
    746  1.1.1.5  mrg 
    747  1.1.1.5  mrg           mpfr_clear_flags ();
    748  1.1.1.5  mrg           inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
    749  1.1.1.5  mrg           flags2 = __gmpfr_flags;
    750  1.1.1.5  mrg 
    751  1.1.1.5  mrg           if (! (mpfr_equal_p (s1, s2) &&
    752  1.1.1.5  mrg                  SAME_SIGN (inex1, inex2) &&
    753  1.1.1.5  mrg                  flags1 == flags2))
    754  1.1.1.5  mrg             {
    755  1.1.1.5  mrg               printf ("Error in test_underflow4 for neg=%u %s\n",
    756  1.1.1.5  mrg                       neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    757  1.1.1.5  mrg               printf ("Expected ");
    758  1.1.1.5  mrg               mpfr_dump (s1);
    759  1.1.1.5  mrg               printf ("  with inex ~ %d, flags =", inex1);
    760  1.1.1.5  mrg               flags_out (flags1);
    761  1.1.1.5  mrg               printf ("Got      ");
    762  1.1.1.5  mrg               mpfr_dump (s2);
    763  1.1.1.5  mrg               printf ("  with inex ~ %d, flags =", inex2);
    764  1.1.1.5  mrg               flags_out (flags2);
    765  1.1.1.5  mrg               exit (1);
    766  1.1.1.5  mrg             }
    767  1.1.1.5  mrg 
    768  1.1.1.5  mrg           if (neg == 0 || neg == 2)
    769  1.1.1.5  mrg             mpfr_neg (x, x, MPFR_RNDN);
    770  1.1.1.5  mrg           if (neg == 1 || neg == 3)
    771  1.1.1.5  mrg             mpfr_neg (y, y, MPFR_RNDN);
    772  1.1.1.5  mrg           mpfr_neg (z, z, MPFR_RNDN);
    773  1.1.1.5  mrg         }
    774  1.1.1.5  mrg     }
    775  1.1.1.5  mrg 
    776  1.1.1.5  mrg   mpfr_clears (x, y, z, s1, s2, (mpfr_ptr) 0);
    777  1.1.1.5  mrg }
    778  1.1.1.5  mrg 
    779  1.1.1.5  mrg /* Test s = x*y + z on:
    780  1.1.1.5  mrg      x = +/- 2^emin
    781  1.1.1.5  mrg      y = +/- 2^(-3)
    782  1.1.1.5  mrg      z = +/- 2^(emin + PREC(s)) and MPFR numbers close to this value.
    783  1.1.1.5  mrg    with PREC(z) from PREC(s) - 2 to PREC(s) + 8.
    784  1.1.1.5  mrg */
    785  1.1.1.5  mrg static void
    786  1.1.1.5  mrg test_underflow5 (void)
    787  1.1.1.5  mrg {
    788  1.1.1.5  mrg   mpfr_t w, x, y, z, s1, s2, t;
    789  1.1.1.5  mrg   mpfr_exp_t emin;
    790  1.1.1.5  mrg   mpfr_prec_t ps = 32;
    791  1.1.1.5  mrg   int inex, i, j, rnd;
    792  1.1.1.5  mrg   unsigned int neg;
    793  1.1.1.5  mrg 
    794  1.1.1.5  mrg   mpfr_inits2 (MPFR_PREC_MIN, w, x, y, (mpfr_ptr) 0);
    795  1.1.1.5  mrg   mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
    796  1.1.1.5  mrg   mpfr_init2 (t, ps + 9);
    797  1.1.1.5  mrg 
    798  1.1.1.5  mrg   emin = mpfr_get_emin ();
    799  1.1.1.5  mrg 
    800  1.1.1.5  mrg   inex = mpfr_set_si_2exp (w, 1, emin, MPFR_RNDN);  /* w = 2^emin */
    801  1.1.1.5  mrg   MPFR_ASSERTN (inex == 0);
    802  1.1.1.5  mrg   inex = mpfr_set_si (x, 1, MPFR_RNDN);
    803  1.1.1.5  mrg   MPFR_ASSERTN (inex == 0);
    804  1.1.1.5  mrg   inex = mpfr_set_si_2exp (y, 1, -3, MPFR_RNDN);
    805  1.1.1.5  mrg   MPFR_ASSERTN (inex == 0);
    806  1.1.1.5  mrg 
    807  1.1.1.5  mrg   for (i = -2; i <= 8; i++)
    808  1.1.1.5  mrg     {
    809  1.1.1.5  mrg       mpfr_init2 (z, ps + i);
    810  1.1.1.5  mrg       inex = mpfr_set_si_2exp (z, 1, ps, MPFR_RNDN);
    811  1.1.1.5  mrg       MPFR_ASSERTN (inex == 0);
    812  1.1.1.5  mrg 
    813  1.1.1.5  mrg       for (j = 1; j <= 32; j++)
    814  1.1.1.5  mrg         mpfr_nextbelow (z);
    815  1.1.1.5  mrg 
    816  1.1.1.5  mrg       for (j = -32; j <= 32; j++)
    817  1.1.1.5  mrg         {
    818  1.1.1.5  mrg           for (neg = 0; neg < 8; neg++)
    819  1.1.1.5  mrg             {
    820  1.1.1.5  mrg               mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
    821  1.1.1.5  mrg               mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
    822  1.1.1.5  mrg               mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
    823  1.1.1.5  mrg 
    824  1.1.1.5  mrg               inex = mpfr_fma (t, x, y, z, MPFR_RNDN);
    825  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    826  1.1.1.5  mrg 
    827  1.1.1.5  mrg               inex = mpfr_mul (x, x, w, MPFR_RNDN);
    828  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    829  1.1.1.5  mrg               inex = mpfr_mul (z, z, w, MPFR_RNDN);
    830  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    831  1.1.1.5  mrg 
    832  1.1.1.5  mrg               RND_LOOP_NO_RNDF (rnd)
    833  1.1.1.5  mrg                 {
    834  1.1.1.5  mrg                   mpfr_flags_t flags1, flags2;
    835  1.1.1.5  mrg                   int inex1, inex2;
    836  1.1.1.5  mrg 
    837  1.1.1.5  mrg                   mpfr_clear_flags ();
    838  1.1.1.5  mrg                   inex1 = mpfr_mul (s1, w, t, (mpfr_rnd_t) rnd);
    839  1.1.1.5  mrg                   flags1 = __gmpfr_flags;
    840  1.1.1.5  mrg 
    841  1.1.1.5  mrg                   mpfr_clear_flags ();
    842  1.1.1.5  mrg                   inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
    843  1.1.1.5  mrg                   flags2 = __gmpfr_flags;
    844  1.1.1.5  mrg 
    845  1.1.1.5  mrg                   if (! (mpfr_equal_p (s1, s2) &&
    846  1.1.1.5  mrg                          SAME_SIGN (inex1, inex2) &&
    847  1.1.1.5  mrg                          flags1 == flags2))
    848  1.1.1.5  mrg                     {
    849  1.1.1.5  mrg                       printf ("Error in test_underflow5 on "
    850  1.1.1.5  mrg                               "i=%d j=%d neg=%u %s\n", i, j, neg,
    851  1.1.1.5  mrg                               mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    852  1.1.1.5  mrg                       printf ("Expected ");
    853  1.1.1.5  mrg                       mpfr_dump (s1);
    854  1.1.1.5  mrg                       printf ("  with inex ~ %d, flags =", inex1);
    855  1.1.1.5  mrg                       flags_out (flags1);
    856  1.1.1.5  mrg                       printf ("Got      ");
    857  1.1.1.5  mrg                       mpfr_dump (s2);
    858  1.1.1.5  mrg                       printf ("  with inex ~ %d, flags =", inex2);
    859  1.1.1.5  mrg                       flags_out (flags2);
    860  1.1.1.5  mrg                       exit (1);
    861  1.1.1.5  mrg                     }
    862  1.1.1.5  mrg                 }  /* rnd */
    863  1.1.1.5  mrg 
    864  1.1.1.5  mrg               inex = mpfr_div (x, x, w, MPFR_RNDN);
    865  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    866  1.1.1.5  mrg               inex = mpfr_div (z, z, w, MPFR_RNDN);
    867  1.1.1.5  mrg               MPFR_ASSERTN (inex == 0);
    868  1.1.1.5  mrg             }  /* neg */
    869  1.1.1.5  mrg 
    870  1.1.1.5  mrg           MPFR_SET_POS (z);  /* restore the value before the loop on neg */
    871  1.1.1.5  mrg           mpfr_nextabove (z);
    872  1.1.1.5  mrg         }  /* j */
    873  1.1.1.5  mrg 
    874  1.1.1.5  mrg       mpfr_clear (z);
    875  1.1.1.5  mrg     }  /* i */
    876  1.1.1.5  mrg 
    877  1.1.1.5  mrg   mpfr_clears (w, x, y, s1, s2, t, (mpfr_ptr) 0);
    878  1.1.1.5  mrg }
    879  1.1.1.5  mrg 
    880  1.1.1.3  mrg static void
    881      1.1  mrg bug20101018 (void)
    882      1.1  mrg {
    883      1.1  mrg   mpfr_t x, y, z, t, u;
    884      1.1  mrg   int i;
    885      1.1  mrg 
    886      1.1  mrg   mpfr_init2 (x, 64);
    887      1.1  mrg   mpfr_init2 (y, 64);
    888      1.1  mrg   mpfr_init2 (z, 64);
    889      1.1  mrg   mpfr_init2 (t, 64);
    890      1.1  mrg   mpfr_init2 (u, 64);
    891      1.1  mrg 
    892      1.1  mrg   mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN);
    893      1.1  mrg   mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN);
    894      1.1  mrg   mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN);
    895      1.1  mrg   mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN);
    896      1.1  mrg   i = mpfr_fma (u, x, y, z, MPFR_RNDN);
    897  1.1.1.3  mrg   if (! mpfr_equal_p (u, t))
    898      1.1  mrg     {
    899      1.1  mrg       printf ("Wrong result in bug20101018 (a)\n");
    900      1.1  mrg       printf ("Expected ");
    901      1.1  mrg       mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
    902      1.1  mrg       printf ("\nGot      ");
    903      1.1  mrg       mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
    904      1.1  mrg       printf ("\n");
    905      1.1  mrg       exit (1);
    906      1.1  mrg     }
    907      1.1  mrg   if (i <= 0)
    908      1.1  mrg     {
    909      1.1  mrg       printf ("Wrong ternary value in bug20101018 (a)\n");
    910      1.1  mrg       printf ("Expected > 0\n");
    911      1.1  mrg       printf ("Got      %d\n", i);
    912      1.1  mrg       exit (1);
    913      1.1  mrg     }
    914      1.1  mrg 
    915      1.1  mrg   mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN);
    916      1.1  mrg   mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN);
    917      1.1  mrg   mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN);
    918      1.1  mrg   mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN);
    919      1.1  mrg   i = mpfr_fma (u, x, y, z, MPFR_RNDN);
    920  1.1.1.3  mrg   if (! mpfr_equal_p (u, t))
    921      1.1  mrg     {
    922      1.1  mrg       printf ("Wrong result in bug20101018 (b)\n");
    923      1.1  mrg       printf ("Expected ");
    924      1.1  mrg       mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
    925      1.1  mrg       printf ("\nGot      ");
    926      1.1  mrg       mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
    927      1.1  mrg       printf ("\n");
    928      1.1  mrg       exit (1);
    929      1.1  mrg     }
    930      1.1  mrg   if (i <= 0)
    931      1.1  mrg     {
    932      1.1  mrg       printf ("Wrong ternary value in bug20101018 (b)\n");
    933      1.1  mrg       printf ("Expected > 0\n");
    934      1.1  mrg       printf ("Got      %d\n", i);
    935      1.1  mrg       exit (1);
    936      1.1  mrg     }
    937      1.1  mrg 
    938      1.1  mrg   mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN);
    939      1.1  mrg   mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN);
    940      1.1  mrg   mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN);
    941      1.1  mrg   mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN);
    942      1.1  mrg   i = mpfr_fma (u, x, y, z, MPFR_RNDN);
    943  1.1.1.3  mrg   if (! mpfr_equal_p (u, t))
    944      1.1  mrg     {
    945      1.1  mrg       printf ("Wrong result in bug20101018 (c)\n");
    946      1.1  mrg       printf ("Expected ");
    947      1.1  mrg       mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
    948      1.1  mrg       printf ("\nGot      ");
    949      1.1  mrg       mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
    950      1.1  mrg       printf ("\n");
    951      1.1  mrg       exit (1);
    952      1.1  mrg     }
    953      1.1  mrg   if (i <= 0)
    954      1.1  mrg     {
    955      1.1  mrg       printf ("Wrong ternary value in bug20101018 (c)\n");
    956      1.1  mrg       printf ("Expected > 0\n");
    957      1.1  mrg       printf ("Got      %d\n", i);
    958      1.1  mrg       exit (1);
    959      1.1  mrg     }
    960      1.1  mrg 
    961      1.1  mrg   mpfr_clear (x);
    962      1.1  mrg   mpfr_clear (y);
    963      1.1  mrg   mpfr_clear (z);
    964      1.1  mrg   mpfr_clear (t);
    965      1.1  mrg   mpfr_clear (u);
    966      1.1  mrg }
    967      1.1  mrg 
    968  1.1.1.4  mrg /* bug found with GMP_CHECK_RANDOMIZE=1514407719 */
    969  1.1.1.4  mrg static void
    970  1.1.1.4  mrg bug20171219 (void)
    971  1.1.1.4  mrg {
    972  1.1.1.4  mrg   mpfr_t x, y, z, t, u;
    973  1.1.1.4  mrg   int i;
    974  1.1.1.4  mrg 
    975  1.1.1.4  mrg   mpfr_init2 (x, 60);
    976  1.1.1.4  mrg   mpfr_init2 (y, 60);
    977  1.1.1.4  mrg   mpfr_init2 (z, 60);
    978  1.1.1.4  mrg   mpfr_init2 (t, 68);
    979  1.1.1.4  mrg   mpfr_init2 (u, 68);
    980  1.1.1.4  mrg 
    981  1.1.1.4  mrg   mpfr_set_ui (x, 1, MPFR_RNDN);
    982  1.1.1.4  mrg   mpfr_set_ui (y, 1, MPFR_RNDN);
    983  1.1.1.4  mrg   mpfr_set_ui (z, 1, MPFR_RNDN);
    984  1.1.1.4  mrg   mpfr_set_ui (t, 2, MPFR_RNDN);
    985  1.1.1.4  mrg   i = mpfr_fma (u, x, y, z, MPFR_RNDA);
    986  1.1.1.4  mrg   if (! mpfr_equal_p (u, t))
    987  1.1.1.4  mrg     {
    988  1.1.1.4  mrg       printf ("Wrong result in bug20171219 (a)\n");
    989  1.1.1.4  mrg       printf ("Expected ");
    990  1.1.1.4  mrg       mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
    991  1.1.1.4  mrg       printf ("\nGot      ");
    992  1.1.1.4  mrg       mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
    993  1.1.1.4  mrg       printf ("\n");
    994  1.1.1.4  mrg       exit (1);
    995  1.1.1.4  mrg     }
    996  1.1.1.4  mrg   if (i != 0)
    997  1.1.1.4  mrg     {
    998  1.1.1.4  mrg       printf ("Wrong ternary value in bug20171219\n");
    999  1.1.1.4  mrg       printf ("Expected 0\n");
   1000  1.1.1.4  mrg       printf ("Got      %d\n", i);
   1001  1.1.1.4  mrg       exit (1);
   1002  1.1.1.4  mrg     }
   1003  1.1.1.4  mrg 
   1004  1.1.1.4  mrg   mpfr_clear (x);
   1005  1.1.1.4  mrg   mpfr_clear (y);
   1006  1.1.1.4  mrg   mpfr_clear (z);
   1007  1.1.1.4  mrg   mpfr_clear (t);
   1008  1.1.1.4  mrg   mpfr_clear (u);
   1009  1.1.1.4  mrg }
   1010  1.1.1.4  mrg 
   1011  1.1.1.5  mrg /* coverage test for mpfr_set_1_2, case prec < GMP_NUMB_BITS,
   1012  1.1.1.5  mrg    inex > 0, rb <> 0, sb = 0 */
   1013  1.1.1.5  mrg static void
   1014  1.1.1.5  mrg coverage (void)
   1015  1.1.1.5  mrg {
   1016  1.1.1.5  mrg   mpfr_t x, y, z, s;
   1017  1.1.1.5  mrg   int inex;
   1018  1.1.1.5  mrg   mpfr_exp_t emax;
   1019  1.1.1.5  mrg 
   1020  1.1.1.5  mrg   mpfr_inits2 (GMP_NUMB_BITS - 1, x, y, z, s, (mpfr_ptr) 0);
   1021  1.1.1.5  mrg 
   1022  1.1.1.5  mrg   /* set x to 2^(GMP_NUMB_BITS/2) + 1, y to 2^(GMP_NUMB_BITS/2) - 1 */
   1023  1.1.1.5  mrg   MPFR_ASSERTN((GMP_NUMB_BITS % 2) == 0);
   1024  1.1.1.5  mrg   mpfr_set_ui_2exp (x, 1, GMP_NUMB_BITS / 2, MPFR_RNDN);
   1025  1.1.1.5  mrg   mpfr_sub_ui (y, x, 1, MPFR_RNDN);
   1026  1.1.1.5  mrg   mpfr_add_ui (x, x, 1, MPFR_RNDN);
   1027  1.1.1.5  mrg   /* we have x*y = 2^GMP_NUMB_BITS - 1, thus has exponent GMP_NUMB_BITS */
   1028  1.1.1.5  mrg   /* set z to 2^(1-GMP_NUMB_BITS), with exponent 2-GMP_NUMB_BITS */
   1029  1.1.1.5  mrg   mpfr_set_ui_2exp (z, 1, 1 - GMP_NUMB_BITS, MPFR_RNDN);
   1030  1.1.1.5  mrg   inex = mpfr_fms (s, x, y, z, MPFR_RNDN);
   1031  1.1.1.5  mrg   /* s should be 2^GMP_NUMB_BITS-2 */
   1032  1.1.1.5  mrg   MPFR_ASSERTN(inex < 0);
   1033  1.1.1.5  mrg   inex = mpfr_add_ui (s, s, 2, MPFR_RNDN);
   1034  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (s, 1, GMP_NUMB_BITS) == 0);
   1035  1.1.1.5  mrg 
   1036  1.1.1.5  mrg   /* same example, but with overflow */
   1037  1.1.1.5  mrg   emax = mpfr_get_emax ();
   1038  1.1.1.6  mrg   set_emax (GMP_NUMB_BITS + 1);
   1039  1.1.1.5  mrg   mpfr_set_ui_2exp (z, 1, mpfr_get_emax () - 1, MPFR_RNDZ);
   1040  1.1.1.5  mrg   mpfr_clear_flags ();
   1041  1.1.1.5  mrg   inex = mpfr_fma (s, x, y, z, MPFR_RNDN);
   1042  1.1.1.5  mrg   /* x*y = 2^GMP_NUMB_BITS - 1, z = 2^GMP_NUMB_BITS, thus
   1043  1.1.1.5  mrg      x*y+z = 2^(GMP_NUMB_BITS+1) - 1 should round to 2^(GMP_NUMB_BITS+1),
   1044  1.1.1.5  mrg      thus give an overflow */
   1045  1.1.1.5  mrg   MPFR_ASSERTN(inex > 0);
   1046  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_inf_p (s) && mpfr_sgn (s) > 0);
   1047  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_overflow_p ());
   1048  1.1.1.6  mrg   set_emax (emax);
   1049  1.1.1.5  mrg 
   1050  1.1.1.5  mrg   mpfr_clear (x);
   1051  1.1.1.5  mrg   mpfr_clear (y);
   1052  1.1.1.5  mrg   mpfr_clear (z);
   1053  1.1.1.5  mrg   mpfr_clear (s);
   1054  1.1.1.5  mrg }
   1055  1.1.1.5  mrg 
   1056      1.1  mrg int
   1057      1.1  mrg main (int argc, char *argv[])
   1058      1.1  mrg {
   1059      1.1  mrg   mpfr_t x, y, z, s;
   1060  1.1.1.3  mrg   mpfr_exp_t emin, emax;
   1061  1.1.1.5  mrg   int i;
   1062      1.1  mrg 
   1063      1.1  mrg   tests_start_mpfr ();
   1064      1.1  mrg 
   1065  1.1.1.5  mrg   coverage ();
   1066  1.1.1.5  mrg 
   1067  1.1.1.3  mrg   emin = mpfr_get_emin ();
   1068  1.1.1.3  mrg   emax = mpfr_get_emax ();
   1069  1.1.1.3  mrg 
   1070  1.1.1.4  mrg   bug20171219 ();
   1071      1.1  mrg   bug20101018 ();
   1072      1.1  mrg 
   1073      1.1  mrg   mpfr_init (x);
   1074      1.1  mrg   mpfr_init (s);
   1075      1.1  mrg   mpfr_init (y);
   1076      1.1  mrg   mpfr_init (z);
   1077      1.1  mrg 
   1078      1.1  mrg   /* check special cases */
   1079      1.1  mrg   mpfr_set_prec (x, 2);
   1080      1.1  mrg   mpfr_set_prec (y, 2);
   1081      1.1  mrg   mpfr_set_prec (z, 2);
   1082      1.1  mrg   mpfr_set_prec (s, 2);
   1083      1.1  mrg   mpfr_set_str (x, "-0.75", 10, MPFR_RNDN);
   1084      1.1  mrg   mpfr_set_str (y, "0.5", 10, MPFR_RNDN);
   1085      1.1  mrg   mpfr_set_str (z, "0.375", 10, MPFR_RNDN);
   1086      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDU); /* result is 0 */
   1087  1.1.1.4  mrg   if (mpfr_cmp_ui (s, 0))
   1088      1.1  mrg     {
   1089  1.1.1.4  mrg       printf ("Error: -0.75 * 0.5 + 0.375 should be equal to 0 for prec=2\n");
   1090  1.1.1.4  mrg       printf ("got instead ");
   1091  1.1.1.4  mrg       mpfr_dump (s);
   1092  1.1.1.4  mrg       exit (1);
   1093      1.1  mrg     }
   1094      1.1  mrg 
   1095      1.1  mrg   mpfr_set_prec (x, 27);
   1096      1.1  mrg   mpfr_set_prec (y, 27);
   1097      1.1  mrg   mpfr_set_prec (z, 27);
   1098      1.1  mrg   mpfr_set_prec (s, 27);
   1099      1.1  mrg   mpfr_set_str_binary (x, "1.11111111111111111111111111e-1");
   1100      1.1  mrg   mpfr_set (y, x, MPFR_RNDN);
   1101      1.1  mrg   mpfr_set_str_binary (z, "-1.00011110100011001011001001e-1");
   1102      1.1  mrg   if (mpfr_fma (s, x, y, z, MPFR_RNDN) >= 0)
   1103      1.1  mrg     {
   1104      1.1  mrg       printf ("Wrong inexact flag for x=y=1-2^(-27)\n");
   1105      1.1  mrg       exit (1);
   1106      1.1  mrg     }
   1107      1.1  mrg 
   1108      1.1  mrg   mpfr_set_nan (x);
   1109      1.1  mrg   mpfr_urandomb (y, RANDS);
   1110      1.1  mrg   mpfr_urandomb (z, RANDS);
   1111      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1112      1.1  mrg   if (!mpfr_nan_p (s))
   1113      1.1  mrg     {
   1114  1.1.1.4  mrg       printf ("evaluation of function in x=NAN does not return NAN\n");
   1115      1.1  mrg       exit (1);
   1116      1.1  mrg     }
   1117      1.1  mrg 
   1118      1.1  mrg   mpfr_set_nan (y);
   1119      1.1  mrg   mpfr_urandomb (x, RANDS);
   1120      1.1  mrg   mpfr_urandomb (z, RANDS);
   1121      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1122      1.1  mrg   if (!mpfr_nan_p(s))
   1123      1.1  mrg     {
   1124  1.1.1.4  mrg       printf ("evaluation of function in y=NAN does not return NAN\n");
   1125      1.1  mrg       exit (1);
   1126      1.1  mrg     }
   1127      1.1  mrg 
   1128      1.1  mrg   mpfr_set_nan (z);
   1129      1.1  mrg   mpfr_urandomb (y, RANDS);
   1130      1.1  mrg   mpfr_urandomb (x, RANDS);
   1131      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1132      1.1  mrg   if (!mpfr_nan_p (s))
   1133      1.1  mrg     {
   1134  1.1.1.4  mrg       printf ("evaluation of function in z=NAN does not return NAN\n");
   1135      1.1  mrg       exit (1);
   1136      1.1  mrg     }
   1137      1.1  mrg 
   1138      1.1  mrg   mpfr_set_inf (x, 1);
   1139      1.1  mrg   mpfr_set_inf (y, 1);
   1140      1.1  mrg   mpfr_set_inf (z, 1);
   1141      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1142      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
   1143      1.1  mrg     {
   1144      1.1  mrg       printf ("Error for (+inf) * (+inf) + (+inf)\n");
   1145      1.1  mrg       exit (1);
   1146      1.1  mrg     }
   1147      1.1  mrg 
   1148      1.1  mrg   mpfr_set_inf (x, -1);
   1149      1.1  mrg   mpfr_set_inf (y, -1);
   1150      1.1  mrg   mpfr_set_inf (z, 1);
   1151      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1152      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
   1153      1.1  mrg     {
   1154      1.1  mrg       printf ("Error for (-inf) * (-inf) + (+inf)\n");
   1155      1.1  mrg       exit (1);
   1156      1.1  mrg     }
   1157      1.1  mrg 
   1158      1.1  mrg   mpfr_set_inf (x, 1);
   1159      1.1  mrg   mpfr_set_inf (y, -1);
   1160      1.1  mrg   mpfr_set_inf (z, -1);
   1161      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1162      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
   1163      1.1  mrg     {
   1164      1.1  mrg       printf ("Error for (+inf) * (-inf) + (-inf)\n");
   1165      1.1  mrg       exit (1);
   1166      1.1  mrg     }
   1167      1.1  mrg 
   1168      1.1  mrg   mpfr_set_inf (x, -1);
   1169      1.1  mrg   mpfr_set_inf (y, 1);
   1170      1.1  mrg   mpfr_set_inf (z, -1);
   1171      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1172      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
   1173      1.1  mrg     {
   1174      1.1  mrg       printf ("Error for (-inf) * (+inf) + (-inf)\n");
   1175      1.1  mrg       exit (1);
   1176      1.1  mrg     }
   1177      1.1  mrg 
   1178      1.1  mrg   mpfr_set_inf (x, 1);
   1179      1.1  mrg   mpfr_set_ui (y, 0, MPFR_RNDN);
   1180      1.1  mrg   mpfr_urandomb (z, RANDS);
   1181      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1182      1.1  mrg   if (!mpfr_nan_p (s))
   1183      1.1  mrg     {
   1184  1.1.1.4  mrg       printf ("evaluation of function in x=INF y=0  does not return NAN\n");
   1185      1.1  mrg       exit (1);
   1186      1.1  mrg     }
   1187      1.1  mrg 
   1188      1.1  mrg   mpfr_set_inf (y, 1);
   1189      1.1  mrg   mpfr_set_ui (x, 0, MPFR_RNDN);
   1190      1.1  mrg   mpfr_urandomb (z, RANDS);
   1191      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1192      1.1  mrg   if (!mpfr_nan_p (s))
   1193      1.1  mrg     {
   1194  1.1.1.4  mrg       printf ("evaluation of function in x=0 y=INF does not return NAN\n");
   1195      1.1  mrg       exit (1);
   1196      1.1  mrg     }
   1197      1.1  mrg 
   1198      1.1  mrg   mpfr_set_inf (x, 1);
   1199      1.1  mrg   mpfr_urandomb (y, RANDS); /* always positive */
   1200      1.1  mrg   mpfr_set_inf (z, -1);
   1201      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1202      1.1  mrg   if (!mpfr_nan_p (s))
   1203      1.1  mrg     {
   1204  1.1.1.4  mrg       printf ("evaluation of function in x=INF y>0 z=-INF does not return NAN\n");
   1205      1.1  mrg       exit (1);
   1206      1.1  mrg     }
   1207      1.1  mrg 
   1208      1.1  mrg   mpfr_set_inf (y, 1);
   1209      1.1  mrg   mpfr_urandomb (x, RANDS);
   1210      1.1  mrg   mpfr_set_inf (z, -1);
   1211      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1212      1.1  mrg   if (!mpfr_nan_p (s))
   1213      1.1  mrg     {
   1214  1.1.1.4  mrg       printf ("evaluation of function in x>0 y=INF z=-INF does not return NAN\n");
   1215      1.1  mrg       exit (1);
   1216      1.1  mrg     }
   1217      1.1  mrg 
   1218      1.1  mrg   mpfr_set_inf (x, 1);
   1219  1.1.1.4  mrg   do mpfr_urandomb (y, RANDS); while (MPFR_IS_ZERO(y));
   1220      1.1  mrg   mpfr_urandomb (z, RANDS);
   1221      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1222      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
   1223      1.1  mrg     {
   1224  1.1.1.4  mrg       printf ("evaluation of function in x=INF does not return INF\n");
   1225      1.1  mrg       exit (1);
   1226      1.1  mrg     }
   1227      1.1  mrg 
   1228      1.1  mrg   mpfr_set_inf (y, 1);
   1229  1.1.1.4  mrg   do mpfr_urandomb (x, RANDS); while (MPFR_IS_ZERO(x));
   1230      1.1  mrg   mpfr_urandomb (z, RANDS);
   1231      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1232      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
   1233      1.1  mrg     {
   1234  1.1.1.4  mrg       printf ("evaluation of function at y=INF does not return INF\n");
   1235      1.1  mrg       exit (1);
   1236      1.1  mrg     }
   1237      1.1  mrg 
   1238      1.1  mrg   mpfr_set_inf (z, 1);
   1239      1.1  mrg   mpfr_urandomb (x, RANDS);
   1240      1.1  mrg   mpfr_urandomb (y, RANDS);
   1241      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1242      1.1  mrg   if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
   1243      1.1  mrg     {
   1244  1.1.1.4  mrg       printf ("evaluation of function in z=INF does not return INF\n");
   1245      1.1  mrg       exit (1);
   1246      1.1  mrg     }
   1247      1.1  mrg 
   1248      1.1  mrg   mpfr_set_ui (x, 0, MPFR_RNDN);
   1249      1.1  mrg   mpfr_urandomb (y, RANDS);
   1250      1.1  mrg   mpfr_urandomb (z, RANDS);
   1251      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1252  1.1.1.3  mrg   if (! mpfr_equal_p (s, z))
   1253      1.1  mrg     {
   1254      1.1  mrg       printf ("evaluation of function in x=0 does not return z\n");
   1255      1.1  mrg       exit (1);
   1256      1.1  mrg     }
   1257      1.1  mrg 
   1258      1.1  mrg   mpfr_set_ui (y, 0, MPFR_RNDN);
   1259      1.1  mrg   mpfr_urandomb (x, RANDS);
   1260      1.1  mrg   mpfr_urandomb (z, RANDS);
   1261      1.1  mrg   mpfr_fma (s, x, y, z, MPFR_RNDN);
   1262  1.1.1.3  mrg   if (! mpfr_equal_p (s, z))
   1263      1.1  mrg     {
   1264      1.1  mrg       printf ("evaluation of function in y=0 does not return z\n");
   1265      1.1  mrg       exit (1);
   1266      1.1  mrg     }
   1267      1.1  mrg 
   1268      1.1  mrg   {
   1269      1.1  mrg     mpfr_prec_t prec;
   1270      1.1  mrg     mpfr_t t, slong;
   1271      1.1  mrg     mpfr_rnd_t rnd;
   1272      1.1  mrg     int inexact, compare;
   1273      1.1  mrg     unsigned int n;
   1274      1.1  mrg 
   1275  1.1.1.3  mrg     mpfr_prec_t p0 = 2, p1 = 200;
   1276  1.1.1.3  mrg     unsigned int N = 200;
   1277      1.1  mrg 
   1278      1.1  mrg     mpfr_init (t);
   1279      1.1  mrg     mpfr_init (slong);
   1280      1.1  mrg 
   1281      1.1  mrg     /* generic test */
   1282      1.1  mrg     for (prec = p0; prec <= p1; prec++)
   1283  1.1.1.3  mrg       {
   1284  1.1.1.3  mrg         mpfr_set_prec (x, prec);
   1285  1.1.1.3  mrg         mpfr_set_prec (y, prec);
   1286  1.1.1.3  mrg         mpfr_set_prec (z, prec);
   1287  1.1.1.3  mrg         mpfr_set_prec (s, prec);
   1288  1.1.1.3  mrg         mpfr_set_prec (t, prec);
   1289      1.1  mrg 
   1290  1.1.1.3  mrg         for (n = 0; n < N; n++)
   1291  1.1.1.3  mrg           {
   1292  1.1.1.3  mrg             mpfr_urandomb (x, RANDS);
   1293  1.1.1.3  mrg             mpfr_urandomb (y, RANDS);
   1294  1.1.1.3  mrg             mpfr_urandomb (z, RANDS);
   1295  1.1.1.3  mrg 
   1296  1.1.1.6  mrg             if (RAND_BOOL ())
   1297  1.1.1.3  mrg               mpfr_neg (x, x, MPFR_RNDN);
   1298  1.1.1.6  mrg             if (RAND_BOOL ())
   1299  1.1.1.3  mrg               mpfr_neg (y, y, MPFR_RNDN);
   1300  1.1.1.6  mrg             if (RAND_BOOL ())
   1301  1.1.1.3  mrg               mpfr_neg (z, z, MPFR_RNDN);
   1302  1.1.1.3  mrg 
   1303  1.1.1.4  mrg             rnd = RND_RAND_NO_RNDF ();
   1304  1.1.1.3  mrg             mpfr_set_prec (slong, 2 * prec);
   1305  1.1.1.3  mrg             if (mpfr_mul (slong, x, y, rnd))
   1306  1.1.1.3  mrg               {
   1307  1.1.1.3  mrg                 printf ("x*y should be exact\n");
   1308  1.1.1.3  mrg                 exit (1);
   1309  1.1.1.3  mrg               }
   1310  1.1.1.3  mrg             compare = mpfr_add (t, slong, z, rnd);
   1311  1.1.1.3  mrg             inexact = mpfr_fma (s, x, y, z, rnd);
   1312  1.1.1.3  mrg             if (! mpfr_equal_p (s, t))
   1313  1.1.1.3  mrg               {
   1314  1.1.1.4  mrg                 printf ("results differ for\n");
   1315  1.1.1.4  mrg                 printf ("  x=");
   1316  1.1.1.4  mrg                 mpfr_dump (x);
   1317  1.1.1.3  mrg                 printf ("  y=");
   1318  1.1.1.4  mrg                 mpfr_dump (y);
   1319  1.1.1.3  mrg                 printf ("  z=");
   1320  1.1.1.4  mrg                 mpfr_dump (z);
   1321  1.1.1.4  mrg                 printf ("  with prec=%u rnd_mode=%s\n", (unsigned int) prec,
   1322  1.1.1.3  mrg                         mpfr_print_rnd_mode (rnd));
   1323  1.1.1.3  mrg                 printf ("got      ");
   1324  1.1.1.4  mrg                 mpfr_dump (s);
   1325  1.1.1.3  mrg                 printf ("expected ");
   1326  1.1.1.4  mrg                 mpfr_dump (t);
   1327  1.1.1.4  mrg                 printf ("approx   ");
   1328  1.1.1.4  mrg                 mpfr_dump (slong);
   1329  1.1.1.3  mrg                 exit (1);
   1330  1.1.1.3  mrg               }
   1331  1.1.1.3  mrg             if (! SAME_SIGN (inexact, compare))
   1332  1.1.1.3  mrg               {
   1333  1.1.1.3  mrg                 printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
   1334  1.1.1.3  mrg                         mpfr_print_rnd_mode (rnd), compare, inexact);
   1335  1.1.1.4  mrg                 printf (" x="); mpfr_dump (x);
   1336  1.1.1.4  mrg                 printf (" y="); mpfr_dump (y);
   1337  1.1.1.4  mrg                 printf (" z="); mpfr_dump (z);
   1338  1.1.1.4  mrg                 printf (" s="); mpfr_dump (s);
   1339  1.1.1.3  mrg                 exit (1);
   1340  1.1.1.3  mrg               }
   1341  1.1.1.3  mrg           }
   1342  1.1.1.3  mrg       }
   1343  1.1.1.3  mrg     mpfr_clear (t);
   1344  1.1.1.3  mrg     mpfr_clear (slong);
   1345      1.1  mrg 
   1346      1.1  mrg   }
   1347      1.1  mrg   mpfr_clear (x);
   1348      1.1  mrg   mpfr_clear (y);
   1349      1.1  mrg   mpfr_clear (z);
   1350      1.1  mrg   mpfr_clear (s);
   1351      1.1  mrg 
   1352      1.1  mrg   test_exact ();
   1353      1.1  mrg 
   1354  1.1.1.5  mrg   for (i = 0; i <= 2; i++)
   1355  1.1.1.5  mrg     {
   1356  1.1.1.5  mrg       if (i == 0)
   1357  1.1.1.5  mrg         {
   1358  1.1.1.5  mrg           /* corresponds to the generic code + mpfr_check_range */
   1359  1.1.1.5  mrg           set_emin (-1024);
   1360  1.1.1.5  mrg           set_emax (1024);
   1361  1.1.1.5  mrg         }
   1362  1.1.1.5  mrg       else if (i == 1)
   1363  1.1.1.5  mrg         {
   1364  1.1.1.5  mrg           set_emin (MPFR_EMIN_MIN);
   1365  1.1.1.5  mrg           set_emax (MPFR_EMAX_MAX);
   1366  1.1.1.5  mrg         }
   1367  1.1.1.5  mrg       else
   1368  1.1.1.5  mrg         {
   1369  1.1.1.5  mrg           MPFR_ASSERTN (i == 2);
   1370  1.1.1.5  mrg           if (emin == MPFR_EMIN_MIN && emax == MPFR_EMAX_MAX)
   1371  1.1.1.5  mrg             break;
   1372  1.1.1.5  mrg           set_emin (emin);
   1373  1.1.1.5  mrg           set_emax (emax);
   1374  1.1.1.5  mrg         }
   1375  1.1.1.5  mrg 
   1376  1.1.1.5  mrg       test_overflow1 ();
   1377  1.1.1.5  mrg       test_overflow2 ();
   1378  1.1.1.5  mrg       test_overflow3 ();
   1379  1.1.1.5  mrg       test_overflow4 ();
   1380  1.1.1.5  mrg       test_overflow5 ();
   1381  1.1.1.5  mrg       test_underflow1 ();
   1382  1.1.1.5  mrg       test_underflow2 ();
   1383  1.1.1.5  mrg       test_underflow3 (i);
   1384  1.1.1.5  mrg       test_underflow4 ();
   1385  1.1.1.5  mrg       test_underflow5 ();
   1386  1.1.1.5  mrg     }
   1387      1.1  mrg 
   1388      1.1  mrg   tests_end_mpfr ();
   1389      1.1  mrg   return 0;
   1390      1.1  mrg }
   1391