Home | History | Annotate | Line # | Download | only in tests
      1  1.1       mrg /* Test file for mpfr_exp.
      2  1.1       mrg 
      3  1.7       mrg Copyright 1999, 2001-2023 Free Software Foundation, Inc.
      4  1.4       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.6       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 #ifdef CHECK_EXTERNAL
     26  1.1       mrg static int
     27  1.1       mrg test_exp (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
     28  1.1       mrg {
     29  1.1       mrg   int res;
     30  1.1       mrg   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
     31  1.1       mrg   if (ok)
     32  1.1       mrg     {
     33  1.1       mrg       mpfr_print_raw (b);
     34  1.1       mrg     }
     35  1.1       mrg   res = mpfr_exp (a, b, rnd_mode);
     36  1.1       mrg   if (ok)
     37  1.1       mrg     {
     38  1.1       mrg       printf (" ");
     39  1.1       mrg       mpfr_print_raw (a);
     40  1.1       mrg       printf ("\n");
     41  1.1       mrg     }
     42  1.1       mrg   return res;
     43  1.1       mrg }
     44  1.1       mrg #else
     45  1.1       mrg #define test_exp mpfr_exp
     46  1.1       mrg #endif
     47  1.1       mrg 
     48  1.1       mrg /* returns the number of ulp of error */
     49  1.1       mrg static void
     50  1.1       mrg check3 (const char *op, mpfr_rnd_t rnd, const char *res)
     51  1.1       mrg {
     52  1.1       mrg   mpfr_t x, y;
     53  1.1       mrg 
     54  1.1       mrg   mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
     55  1.1       mrg   /* y negative. If we forget to set the sign in mpfr_exp, we'll see it. */
     56  1.1       mrg   mpfr_set_si (y, -1, MPFR_RNDN);
     57  1.1       mrg   mpfr_set_str1 (x, op);
     58  1.1       mrg   test_exp (y, x, rnd);
     59  1.1       mrg   if (mpfr_cmp_str1 (y, res) )
     60  1.1       mrg     {
     61  1.1       mrg       printf ("mpfr_exp failed for x=%s, rnd=%s\n",
     62  1.1       mrg               op, mpfr_print_rnd_mode (rnd));
     63  1.1       mrg       printf ("expected result is %s, got ", res);
     64  1.1       mrg       mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
     65  1.1       mrg       putchar('\n');
     66  1.1       mrg       exit (1);
     67  1.1       mrg     }
     68  1.1       mrg   mpfr_clears (x, y, (mpfr_ptr) 0);
     69  1.1       mrg }
     70  1.1       mrg 
     71  1.1       mrg /* expx is the value of exp(X) rounded toward -infinity */
     72  1.1       mrg static void
     73  1.1       mrg check_worst_case (const char *Xs, const char *expxs)
     74  1.1       mrg {
     75  1.1       mrg   mpfr_t x, y;
     76  1.1       mrg 
     77  1.1       mrg   mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
     78  1.1       mrg   mpfr_set_str1(x, Xs);
     79  1.1       mrg   test_exp(y, x, MPFR_RNDD);
     80  1.1       mrg   if (mpfr_cmp_str1 (y, expxs))
     81  1.1       mrg     {
     82  1.1       mrg       printf ("exp(x) rounded toward -infinity is wrong\n");
     83  1.1       mrg       exit(1);
     84  1.1       mrg     }
     85  1.1       mrg   mpfr_set_str1(x, Xs);
     86  1.1       mrg   test_exp(x, x, MPFR_RNDU);
     87  1.1       mrg   mpfr_nexttoinf (y);
     88  1.1       mrg   if (mpfr_cmp(x,y))
     89  1.1       mrg     {
     90  1.1       mrg       printf ("exp(x) rounded toward +infinity is wrong\n");
     91  1.1       mrg       exit(1);
     92  1.1       mrg     }
     93  1.1       mrg   mpfr_clears (x, y, (mpfr_ptr) 0);
     94  1.1       mrg }
     95  1.1       mrg 
     96  1.1       mrg /* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */
     97  1.1       mrg static int
     98  1.1       mrg check_worst_cases (void)
     99  1.1       mrg {
    100  1.1       mrg   mpfr_t x; mpfr_t y;
    101  1.1       mrg 
    102  1.1       mrg   mpfr_init(x);
    103  1.1       mrg   mpfr_set_prec (x, 53);
    104  1.1       mrg 
    105  1.1       mrg   check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204");
    106  1.1       mrg   check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680");
    107  1.1       mrg   check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907");
    108  1.1       mrg   check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702");
    109  1.1       mrg   check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906");
    110  1.1       mrg   check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676");
    111  1.1       mrg   check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881");
    112  1.1       mrg   /* bug found by Vincent Lefe`vre on December 8, 1999 */
    113  1.1       mrg   check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236");
    114  1.1       mrg   /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */
    115  1.1       mrg   check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622");
    116  1.1       mrg   check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757");
    117  1.1       mrg   check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832");
    118  1.1       mrg   check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792");
    119  1.1       mrg   check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835");
    120  1.1       mrg   check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425");
    121  1.1       mrg 
    122  1.1       mrg   mpfr_set_prec (x, 601);
    123  1.1       mrg   mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ);
    124  1.1       mrg   mpfr_init2 (y, 601);
    125  1.1       mrg   mpfr_exp_2 (y, x, MPFR_RNDD);
    126  1.1       mrg   mpfr_exp_3 (x, x, MPFR_RNDD);
    127  1.1       mrg   if (mpfr_cmp (x, y))
    128  1.1       mrg     {
    129  1.1       mrg       printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n");
    130  1.1       mrg       printf ("mpfr_exp_2 gives ");
    131  1.1       mrg       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
    132  1.1       mrg       printf ("\nmpfr_exp_3 gives ");
    133  1.1       mrg       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
    134  1.1       mrg       printf ("\n");
    135  1.1       mrg       exit (1);
    136  1.1       mrg     }
    137  1.1       mrg 
    138  1.1       mrg   mpfr_set_prec (x, 13001);
    139  1.1       mrg   mpfr_set_prec (y, 13001);
    140  1.1       mrg   mpfr_urandomb (x, RANDS);
    141  1.1       mrg   mpfr_exp_3 (y, x, MPFR_RNDN);
    142  1.1       mrg   mpfr_exp_2 (x, x, MPFR_RNDN);
    143  1.1       mrg   if (mpfr_cmp (x, y))
    144  1.1       mrg     {
    145  1.1       mrg       printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n");
    146  1.1       mrg       exit (1);
    147  1.1       mrg     }
    148  1.1       mrg 
    149  1.4       mrg   mpfr_set_prec (x, 118);
    150  1.4       mrg   mpfr_set_str_binary (x, "0.1110010100011101010000111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-86");
    151  1.4       mrg   mpfr_set_prec (y, 118);
    152  1.4       mrg   mpfr_exp_2 (y, x, MPFR_RNDU);
    153  1.4       mrg   mpfr_exp_3 (x, x, MPFR_RNDU);
    154  1.4       mrg   if (mpfr_cmp (x, y))
    155  1.4       mrg     {
    156  1.4       mrg       printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=118\n");
    157  1.4       mrg       printf ("mpfr_exp_2 gives ");
    158  1.4       mrg       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
    159  1.4       mrg       printf ("\nmpfr_exp_3 gives ");
    160  1.4       mrg       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
    161  1.4       mrg       printf ("\n");
    162  1.4       mrg       exit (1);
    163  1.4       mrg     }
    164  1.4       mrg 
    165  1.1       mrg   mpfr_clear (x);
    166  1.1       mrg   mpfr_clear (y);
    167  1.1       mrg   return 0;
    168  1.1       mrg }
    169  1.1       mrg 
    170  1.1       mrg static void
    171  1.1       mrg compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1)
    172  1.1       mrg {
    173  1.1       mrg   mpfr_t x, y, z;
    174  1.1       mrg   mpfr_prec_t prec;
    175  1.1       mrg   mpfr_rnd_t rnd;
    176  1.1       mrg 
    177  1.1       mrg   mpfr_init (x);
    178  1.1       mrg   mpfr_init (y);
    179  1.1       mrg   mpfr_init (z);
    180  1.1       mrg   for (prec = p0; prec <= p1; prec ++)
    181  1.1       mrg     {
    182  1.1       mrg       mpfr_set_prec (x, prec);
    183  1.1       mrg       mpfr_set_prec (y, prec);
    184  1.1       mrg       mpfr_set_prec (z, prec);
    185  1.2  drochner       do
    186  1.2  drochner         mpfr_urandomb (x, RANDS);
    187  1.2  drochner       while (MPFR_IS_ZERO (x));  /* 0 is handled by mpfr_exp only */
    188  1.1       mrg       rnd = RND_RAND ();
    189  1.1       mrg       mpfr_exp_2 (y, x, rnd);
    190  1.1       mrg       mpfr_exp_3 (z, x, rnd);
    191  1.1       mrg       if (mpfr_cmp (y,z))
    192  1.1       mrg         {
    193  1.1       mrg           printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=",
    194  1.1       mrg                   mpfr_print_rnd_mode (rnd));
    195  1.5       mrg           mpfr_dump (x);
    196  1.1       mrg           printf ("mpfr_exp_2 gives ");
    197  1.5       mrg           mpfr_dump (y);
    198  1.1       mrg           printf ("mpfr_exp_3 gives ");
    199  1.5       mrg           mpfr_dump (z);
    200  1.1       mrg           exit (1);
    201  1.1       mrg         }
    202  1.1       mrg   }
    203  1.1       mrg 
    204  1.1       mrg   mpfr_clear (x);
    205  1.1       mrg   mpfr_clear (y);
    206  1.1       mrg   mpfr_clear (z);
    207  1.1       mrg }
    208  1.1       mrg 
    209  1.1       mrg static void
    210  1.1       mrg check_large (void)
    211  1.1       mrg {
    212  1.1       mrg   mpfr_t x, z;
    213  1.1       mrg   mpfr_prec_t prec;
    214  1.1       mrg 
    215  1.1       mrg   /* bug found by Patrick Pe'lissier on 7 Jun 2004 */
    216  1.1       mrg   prec = 203780;
    217  1.1       mrg   mpfr_init2 (x, prec);
    218  1.1       mrg   mpfr_init2 (z, prec);
    219  1.1       mrg   mpfr_set_ui (x, 3, MPFR_RNDN);
    220  1.1       mrg   mpfr_sqrt (x, x, MPFR_RNDN);
    221  1.1       mrg   mpfr_sub_ui (x, x, 1, MPFR_RNDN);
    222  1.1       mrg   mpfr_exp_3 (z, x, MPFR_RNDN);
    223  1.1       mrg   mpfr_clear (x);
    224  1.1       mrg   mpfr_clear (z);
    225  1.1       mrg }
    226  1.1       mrg 
    227  1.1       mrg #define TEST_FUNCTION test_exp
    228  1.1       mrg #define TEST_RANDOM_EMIN -36
    229  1.1       mrg #define TEST_RANDOM_EMAX 36
    230  1.1       mrg #include "tgeneric.c"
    231  1.1       mrg 
    232  1.1       mrg static void
    233  1.1       mrg check_special (void)
    234  1.1       mrg {
    235  1.1       mrg   mpfr_t x, y, z;
    236  1.1       mrg   mpfr_exp_t emin, emax;
    237  1.1       mrg 
    238  1.1       mrg   emin = mpfr_get_emin ();
    239  1.1       mrg   emax = mpfr_get_emax ();
    240  1.1       mrg 
    241  1.1       mrg   mpfr_init (x);
    242  1.1       mrg   mpfr_init (y);
    243  1.1       mrg   mpfr_init (z);
    244  1.1       mrg 
    245  1.1       mrg   /* check exp(NaN) = NaN */
    246  1.1       mrg   mpfr_set_nan (x);
    247  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    248  1.1       mrg   if (!mpfr_nan_p (y))
    249  1.1       mrg     {
    250  1.1       mrg       printf ("Error for exp(NaN)\n");
    251  1.1       mrg       exit (1);
    252  1.1       mrg     }
    253  1.1       mrg 
    254  1.1       mrg   /* check exp(+inf) = +inf */
    255  1.1       mrg   mpfr_set_inf (x, 1);
    256  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    257  1.1       mrg   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    258  1.1       mrg     {
    259  1.1       mrg       printf ("Error for exp(+inf)\n");
    260  1.1       mrg       exit (1);
    261  1.1       mrg     }
    262  1.1       mrg 
    263  1.1       mrg   /* check exp(-inf) = +0 */
    264  1.1       mrg   mpfr_set_inf (x, -1);
    265  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    266  1.5       mrg   if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
    267  1.1       mrg     {
    268  1.1       mrg       printf ("Error for exp(-inf)\n");
    269  1.1       mrg       exit (1);
    270  1.1       mrg     }
    271  1.1       mrg 
    272  1.1       mrg   /* Check overflow. Corner case of mpfr_exp_2 */
    273  1.1       mrg   mpfr_set_prec (x, 64);
    274  1.7       mrg   set_emax (MPFR_EMAX_DEFAULT);
    275  1.7       mrg   set_emin (MPFR_EMIN_DEFAULT);
    276  1.1       mrg   mpfr_set_str (x,
    277  1.1       mrg     "0.1011000101110010000101111111010100001100000001110001100111001101E30",
    278  1.1       mrg                 2, MPFR_RNDN);
    279  1.1       mrg   mpfr_exp (x, x, MPFR_RNDD);
    280  1.1       mrg   if (mpfr_cmp_str (x,
    281  1.1       mrg ".1111111111111111111111111111111111111111111111111111111111111111E1073741823",
    282  1.1       mrg                     2, MPFR_RNDN) != 0)
    283  1.1       mrg     {
    284  1.1       mrg       printf ("Wrong overflow detection in mpfr_exp\n");
    285  1.1       mrg       mpfr_dump (x);
    286  1.1       mrg       exit (1);
    287  1.1       mrg     }
    288  1.1       mrg   /* Check underflow. Corner case of mpfr_exp_2 */
    289  1.1       mrg   mpfr_set_str (x,
    290  1.1       mrg "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
    291  1.1       mrg                 2, MPFR_RNDN);
    292  1.1       mrg   mpfr_exp (x, x, MPFR_RNDN);
    293  1.1       mrg   if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0)
    294  1.1       mrg     {
    295  1.1       mrg       printf ("Wrong underflow (1) detection in mpfr_exp\n");
    296  1.1       mrg       mpfr_dump (x);
    297  1.1       mrg       exit (1);
    298  1.1       mrg     }
    299  1.1       mrg   mpfr_set_str (x,
    300  1.1       mrg "-0.1011001101110010000101111111011111010001110011110111100110111101E30",
    301  1.1       mrg                 2, MPFR_RNDN);
    302  1.1       mrg   mpfr_exp (x, x, MPFR_RNDN);
    303  1.1       mrg   if (mpfr_cmp_ui (x, 0) != 0)
    304  1.1       mrg     {
    305  1.1       mrg       printf ("Wrong underflow (2) detection in mpfr_exp\n");
    306  1.1       mrg       mpfr_dump (x);
    307  1.1       mrg       exit (1);
    308  1.1       mrg     }
    309  1.1       mrg   /* Check overflow. Corner case of mpfr_exp_3 */
    310  1.1       mrg   if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64)
    311  1.1       mrg     {
    312  1.1       mrg       /* this ensures that for small MPFR_EXP_THRESHOLD, the following
    313  1.1       mrg          mpfr_set_str conversion is exact */
    314  1.1       mrg       mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64)
    315  1.1       mrg                        ? MPFR_EXP_THRESHOLD + 10 : 64);
    316  1.1       mrg       mpfr_set_str (x,
    317  1.1       mrg        "0.1011000101110010000101111111010100001100000001110001100111001101E30",
    318  1.1       mrg                     2, MPFR_RNDN);
    319  1.1       mrg       mpfr_clear_overflow ();
    320  1.1       mrg       mpfr_exp (x, x, MPFR_RNDD);
    321  1.1       mrg       if (!mpfr_overflow_p ())
    322  1.1       mrg         {
    323  1.1       mrg           printf ("Wrong overflow detection in mpfr_exp_3\n");
    324  1.1       mrg           mpfr_dump (x);
    325  1.1       mrg           exit (1);
    326  1.1       mrg         }
    327  1.1       mrg       /* Check underflow. Corner case of mpfr_exp_3 */
    328  1.1       mrg       mpfr_set_str (x,
    329  1.1       mrg       "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
    330  1.1       mrg                     2, MPFR_RNDN);
    331  1.1       mrg       mpfr_clear_underflow ();
    332  1.1       mrg       mpfr_exp (x, x, MPFR_RNDN);
    333  1.1       mrg       if (!mpfr_underflow_p ())
    334  1.1       mrg         {
    335  1.1       mrg           printf ("Wrong underflow detection in mpfr_exp_3\n");
    336  1.1       mrg           mpfr_dump (x);
    337  1.1       mrg           exit (1);
    338  1.1       mrg         }
    339  1.1       mrg       mpfr_set_prec (x, 53);
    340  1.1       mrg     }
    341  1.1       mrg 
    342  1.1       mrg   /* check overflow */
    343  1.1       mrg   set_emax (10);
    344  1.1       mrg   mpfr_set_ui (x, 7, MPFR_RNDN);
    345  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    346  1.1       mrg   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
    347  1.1       mrg     {
    348  1.1       mrg       printf ("Error for exp(7) for emax=10\n");
    349  1.1       mrg       exit (1);
    350  1.1       mrg     }
    351  1.1       mrg   set_emax (emax);
    352  1.1       mrg 
    353  1.1       mrg   /* check underflow */
    354  1.1       mrg   set_emin (-10);
    355  1.1       mrg   mpfr_set_si (x, -9, MPFR_RNDN);
    356  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    357  1.5       mrg   if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
    358  1.1       mrg     {
    359  1.1       mrg       printf ("Error for exp(-9) for emin=-10\n");
    360  1.1       mrg       printf ("Expected +0\n");
    361  1.5       mrg       printf ("Got      "); mpfr_dump (y);
    362  1.1       mrg       exit (1);
    363  1.1       mrg     }
    364  1.1       mrg   set_emin (emin);
    365  1.1       mrg 
    366  1.1       mrg   /* check case EXP(x) < -precy */
    367  1.1       mrg   mpfr_set_prec (y, 2);
    368  1.1       mrg   mpfr_set_str_binary (x, "-0.1E-3");
    369  1.1       mrg   test_exp (y, x, MPFR_RNDD);
    370  1.1       mrg   if (mpfr_cmp_ui_2exp (y, 3, -2))
    371  1.1       mrg     {
    372  1.1       mrg       printf ("Error for exp(-1/16), prec=2, RNDD\n");
    373  1.1       mrg       printf ("expected 0.11, got ");
    374  1.1       mrg       mpfr_dump (y);
    375  1.1       mrg       exit (1);
    376  1.1       mrg     }
    377  1.1       mrg   test_exp (y, x, MPFR_RNDZ);
    378  1.1       mrg   if (mpfr_cmp_ui_2exp (y, 3, -2))
    379  1.1       mrg     {
    380  1.1       mrg       printf ("Error for exp(-1/16), prec=2, RNDZ\n");
    381  1.1       mrg       printf ("expected 0.11, got ");
    382  1.1       mrg       mpfr_dump (y);
    383  1.1       mrg       exit (1);
    384  1.1       mrg     }
    385  1.1       mrg   mpfr_set_str_binary (x, "0.1E-3");
    386  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    387  1.1       mrg   if (mpfr_cmp_ui (y, 1))
    388  1.1       mrg     {
    389  1.1       mrg       printf ("Error for exp(1/16), prec=2, RNDN\n");
    390  1.1       mrg       exit (1);
    391  1.1       mrg     }
    392  1.1       mrg   test_exp (y, x, MPFR_RNDU);
    393  1.1       mrg   if (mpfr_cmp_ui_2exp (y, 3, -1))
    394  1.1       mrg     {
    395  1.1       mrg       printf ("Error for exp(1/16), prec=2, RNDU\n");
    396  1.1       mrg       exit (1);
    397  1.1       mrg     }
    398  1.1       mrg 
    399  1.1       mrg   /* bug reported by Franky Backeljauw, 28 Mar 2003 */
    400  1.1       mrg   mpfr_set_prec (x, 53);
    401  1.1       mrg   mpfr_set_prec (y, 53);
    402  1.1       mrg   mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
    403  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    404  1.1       mrg 
    405  1.1       mrg   mpfr_set_prec (x, 153);
    406  1.1       mrg   mpfr_set_prec (z, 153);
    407  1.1       mrg   mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
    408  1.1       mrg   test_exp (z, x, MPFR_RNDN);
    409  1.1       mrg   mpfr_prec_round (z, 53, MPFR_RNDN);
    410  1.1       mrg 
    411  1.1       mrg   if (mpfr_cmp (y, z))
    412  1.1       mrg     {
    413  1.1       mrg       printf ("Error in mpfr_exp for large argument\n");
    414  1.1       mrg       exit (1);
    415  1.1       mrg     }
    416  1.1       mrg 
    417  1.1       mrg   /* corner cases in mpfr_exp_3 */
    418  1.1       mrg   mpfr_set_prec (x, 2);
    419  1.1       mrg   mpfr_set_ui (x, 1, MPFR_RNDN);
    420  1.1       mrg   mpfr_set_prec (y, 2);
    421  1.1       mrg   mpfr_exp_3 (y, x, MPFR_RNDN);
    422  1.1       mrg 
    423  1.1       mrg   /* Check some little things about overflow detection */
    424  1.1       mrg   set_emin (-125);
    425  1.1       mrg   set_emax (128);
    426  1.1       mrg   mpfr_set_prec (x, 107);
    427  1.1       mrg   mpfr_set_prec (y, 107);
    428  1.1       mrg   mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000"
    429  1.1       mrg                        "0000000000000000000000000000000000000000000000000000"
    430  1.1       mrg                        "00000000E4");
    431  1.1       mrg   test_exp (y, x, MPFR_RNDN);
    432  1.1       mrg   if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000"
    433  1.1       mrg                     "1101110111100010111001011111111000110111001011001101010"
    434  1.1       mrg                     "01E22", 2, MPFR_RNDN))
    435  1.1       mrg     {
    436  1.1       mrg       printf ("Special overflow error (1)\n");
    437  1.1       mrg       mpfr_dump (y);
    438  1.1       mrg       exit (1);
    439  1.1       mrg     }
    440  1.1       mrg 
    441  1.1       mrg   set_emin (emin);
    442  1.1       mrg   set_emax (emax);
    443  1.1       mrg 
    444  1.1       mrg   /* Check for overflow producing a segfault with HUGE exponent */
    445  1.1       mrg   mpfr_set_ui  (x, 3, MPFR_RNDN);
    446  1.1       mrg   mpfr_mul_2ui (x, x, 32, MPFR_RNDN);
    447  1.1       mrg   test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/
    448  1.1       mrg 
    449  1.1       mrg   /* Bug due to wrong approximation of (x)/log2 */
    450  1.1       mrg   mpfr_set_prec (x, 163);
    451  1.1       mrg 
    452  1.1       mrg   mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16,
    453  1.1       mrg                 MPFR_RNDN);
    454  1.1       mrg   mpfr_exp (x, x, MPFR_RNDN);
    455  1.1       mrg   if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2",
    456  1.1       mrg                     16, MPFR_RNDN))
    457  1.1       mrg     {
    458  1.1       mrg       printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7");
    459  1.1       mrg       printf ("expected  3.fffffffffffffffffffffffffffffffffffffffe8@-2");
    460  1.1       mrg       printf ("Got       ");
    461  1.1       mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
    462  1.1       mrg     }
    463  1.1       mrg 
    464  1.1       mrg   /* bug found by Guillaume Melquiond, 13 Sep 2005 */
    465  1.1       mrg   mpfr_set_prec (x, 53);
    466  1.1       mrg   mpfr_set_str_binary (x, "-1E-400");
    467  1.1       mrg   mpfr_exp (x, x, MPFR_RNDZ);
    468  1.1       mrg   if (mpfr_cmp_ui (x, 1) == 0)
    469  1.1       mrg     {
    470  1.1       mrg       printf ("Error for exp(-2^(-400))\n");
    471  1.1       mrg       exit (1);
    472  1.1       mrg     }
    473  1.1       mrg 
    474  1.1       mrg   mpfr_clear (x);
    475  1.1       mrg   mpfr_clear (y);
    476  1.1       mrg   mpfr_clear (z);
    477  1.1       mrg }
    478  1.1       mrg 
    479  1.1       mrg /* check sign of inexact flag */
    480  1.1       mrg static void
    481  1.1       mrg check_inexact (void)
    482  1.1       mrg {
    483  1.1       mrg   mpfr_t x, y;
    484  1.1       mrg   int inexact;
    485  1.1       mrg 
    486  1.1       mrg   mpfr_init2 (x, 53);
    487  1.1       mrg   mpfr_init2 (y, 53);
    488  1.1       mrg 
    489  1.1       mrg   mpfr_set_str_binary (x,
    490  1.1       mrg         "1.0000000000001001000110100100101000001101101011100101e2");
    491  1.1       mrg   inexact = test_exp (y, x, MPFR_RNDN);
    492  1.1       mrg   if (inexact <= 0)
    493  1.1       mrg     {
    494  1.1       mrg       printf ("Wrong inexact flag (Got %d instead of 1)\n", inexact);
    495  1.1       mrg       exit (1);
    496  1.1       mrg     }
    497  1.1       mrg 
    498  1.1       mrg   mpfr_clear (x);
    499  1.1       mrg   mpfr_clear (y);
    500  1.1       mrg }
    501  1.1       mrg 
    502  1.1       mrg static void
    503  1.1       mrg check_exp10(void)
    504  1.1       mrg {
    505  1.1       mrg   mpfr_t x;
    506  1.1       mrg   int inexact;
    507  1.1       mrg 
    508  1.1       mrg   mpfr_init2 (x, 200);
    509  1.1       mrg   mpfr_set_ui(x, 4, MPFR_RNDN);
    510  1.1       mrg 
    511  1.1       mrg   inexact = mpfr_exp10 (x, x, MPFR_RNDN);
    512  1.1       mrg   if (mpfr_cmp_ui(x, 10*10*10*10))
    513  1.1       mrg     {
    514  1.1       mrg       printf ("exp10: Wrong returned value\n");
    515  1.1       mrg       exit (1);
    516  1.1       mrg     }
    517  1.1       mrg   if (inexact != 0)
    518  1.1       mrg     {
    519  1.1       mrg       printf ("exp10: Wrong inexact flag\n");
    520  1.1       mrg       exit (1);
    521  1.1       mrg     }
    522  1.1       mrg 
    523  1.1       mrg   mpfr_clear (x);
    524  1.1       mrg }
    525  1.1       mrg 
    526  1.1       mrg static void
    527  1.1       mrg overflowed_exp0 (void)
    528  1.1       mrg {
    529  1.1       mrg   mpfr_t x, y;
    530  1.1       mrg   int emax, i, inex, rnd, err = 0;
    531  1.1       mrg   mpfr_exp_t old_emax;
    532  1.1       mrg 
    533  1.1       mrg   old_emax = mpfr_get_emax ();
    534  1.1       mrg 
    535  1.1       mrg   mpfr_init2 (x, 8);
    536  1.1       mrg   mpfr_init2 (y, 8);
    537  1.1       mrg 
    538  1.1       mrg   for (emax = -1; emax <= 0; emax++)
    539  1.1       mrg     {
    540  1.1       mrg       mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
    541  1.1       mrg       mpfr_nextbelow (y);
    542  1.1       mrg       set_emax (emax);  /* 1 is not representable. */
    543  1.1       mrg       /* and if emax < 0, 1 - eps is not representable either. */
    544  1.1       mrg       for (i = -1; i <= 1; i++)
    545  1.1       mrg         RND_LOOP (rnd)
    546  1.5       mrg           {
    547  1.5       mrg             mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
    548  1.5       mrg             mpfr_clear_flags ();
    549  1.5       mrg             inex = mpfr_exp (x, x, (mpfr_rnd_t) rnd);
    550  1.5       mrg             if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
    551  1.5       mrg                 ! mpfr_overflow_p ())
    552  1.5       mrg               {
    553  1.5       mrg                 printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
    554  1.5       mrg                         "  The overflow flag is not set.\n",
    555  1.5       mrg                         i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    556  1.5       mrg                 err = 1;
    557  1.5       mrg               }
    558  1.5       mrg             if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
    559  1.5       mrg               {
    560  1.5       mrg                 if (inex >= 0)
    561  1.5       mrg                   {
    562  1.5       mrg                     printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
    563  1.5       mrg                             "  The inexact value must be negative.\n",
    564  1.5       mrg                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    565  1.5       mrg                     err = 1;
    566  1.5       mrg                   }
    567  1.5       mrg                 if (! mpfr_equal_p (x, y))
    568  1.5       mrg                   {
    569  1.5       mrg                     printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
    570  1.5       mrg                             "  Got        ", i,
    571  1.5       mrg                             mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    572  1.5       mrg                     mpfr_dump (x);
    573  1.5       mrg                     printf ("  instead of 0.11111111E%d.\n", emax);
    574  1.5       mrg                     err = 1;
    575  1.5       mrg                   }
    576  1.5       mrg               }
    577  1.5       mrg             else if (rnd != MPFR_RNDF)
    578  1.5       mrg               {
    579  1.5       mrg                 if (inex <= 0)
    580  1.5       mrg                   {
    581  1.5       mrg                     printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
    582  1.5       mrg                             "  The inexact value must be positive.\n",
    583  1.5       mrg                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    584  1.5       mrg                     err = 1;
    585  1.5       mrg                   }
    586  1.5       mrg                 if (! (mpfr_inf_p (x) && MPFR_IS_POS (x)))
    587  1.5       mrg                   {
    588  1.5       mrg                     printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
    589  1.5       mrg                             "  Got        ", i,
    590  1.5       mrg                             mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    591  1.5       mrg                     mpfr_dump (x);
    592  1.5       mrg                     printf ("  instead of +Inf.\n");
    593  1.5       mrg                     err = 1;
    594  1.5       mrg                   }
    595  1.5       mrg               }
    596  1.5       mrg           }
    597  1.1       mrg       set_emax (old_emax);
    598  1.1       mrg     }
    599  1.1       mrg 
    600  1.1       mrg   if (err)
    601  1.1       mrg     exit (1);
    602  1.1       mrg   mpfr_clear (x);
    603  1.1       mrg   mpfr_clear (y);
    604  1.1       mrg }
    605  1.1       mrg 
    606  1.1       mrg /* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */
    607  1.1       mrg static void
    608  1.1       mrg bug20080731 (void)
    609  1.1       mrg {
    610  1.1       mrg   mpfr_exp_t emin;
    611  1.1       mrg   mpfr_t x, y1, y2;
    612  1.1       mrg   mpfr_prec_t prec = 64;
    613  1.1       mrg 
    614  1.1       mrg   emin = mpfr_get_emin ();
    615  1.1       mrg   set_emin (MPFR_EMIN_MIN);
    616  1.1       mrg 
    617  1.1       mrg   mpfr_init2 (x, 200);
    618  1.1       mrg   mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7",
    619  1.1       mrg                 16, MPFR_RNDN);
    620  1.1       mrg 
    621  1.6       mrg   /* exp(x) is just below 0xf.fffffffffffffffp-1073741828 */
    622  1.6       mrg 
    623  1.1       mrg   mpfr_init2 (y1, prec);
    624  1.1       mrg   mpfr_exp (y1, x, MPFR_RNDU);
    625  1.1       mrg 
    626  1.1       mrg   /* Compute the result with a higher internal precision. */
    627  1.1       mrg   mpfr_init2 (y2, 300);
    628  1.1       mrg   mpfr_exp (y2, x, MPFR_RNDU);
    629  1.1       mrg   mpfr_prec_round (y2, prec, MPFR_RNDU);
    630  1.1       mrg 
    631  1.1       mrg   if (mpfr_cmp0 (y1, y2) != 0)
    632  1.1       mrg     {
    633  1.1       mrg       printf ("Error in bug20080731\nExpected ");
    634  1.6       mrg       mpfr_dump (y2);
    635  1.1       mrg       printf ("\nGot      ");
    636  1.6       mrg       mpfr_dump (y1);
    637  1.1       mrg       printf ("\n");
    638  1.1       mrg       exit (1);
    639  1.1       mrg     }
    640  1.1       mrg 
    641  1.1       mrg   mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
    642  1.1       mrg   set_emin (emin);
    643  1.1       mrg }
    644  1.1       mrg 
    645  1.1       mrg /* Emulate mpfr_exp with mpfr_exp_3 in the general case. */
    646  1.1       mrg static int
    647  1.1       mrg exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
    648  1.1       mrg {
    649  1.1       mrg   int inexact;
    650  1.1       mrg 
    651  1.1       mrg   inexact = mpfr_exp_3 (y, x, rnd_mode);
    652  1.1       mrg   return mpfr_check_range (y, inexact, rnd_mode);
    653  1.1       mrg }
    654  1.1       mrg 
    655  1.1       mrg static void
    656  1.1       mrg underflow_up (int extended_emin)
    657  1.1       mrg {
    658  1.1       mrg   mpfr_t minpos, x, y, t, t2;
    659  1.1       mrg   int precx, precy;
    660  1.1       mrg   int inex;
    661  1.1       mrg   int rnd;
    662  1.1       mrg   int e3;
    663  1.1       mrg   int i, j;
    664  1.1       mrg 
    665  1.1       mrg   mpfr_init2 (minpos, 2);
    666  1.1       mrg   mpfr_set_ui (minpos, 0, MPFR_RNDN);
    667  1.1       mrg   mpfr_nextabove (minpos);
    668  1.1       mrg 
    669  1.1       mrg   /* Let's test values near the underflow boundary.
    670  1.1       mrg    *
    671  1.1       mrg    * Minimum representable positive number: minpos = 2^(emin - 1).
    672  1.1       mrg    * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small
    673  1.1       mrg    * (note: eps cannot be 0, and cannot be a rational number either).
    674  1.1       mrg    * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2).
    675  1.1       mrg    * We will compute y = rnd(exp(x)) in some rounding mode, precision p.
    676  1.1       mrg    *   1. If eps > 0, then in any rounding mode:
    677  1.1       mrg    *        rnd(exp(x)) >= minpos and no underflow.
    678  1.1       mrg    *      So, let's take x1 = rndu(log(minpos)) in some precision.
    679  1.1       mrg    *   2. If eps < 0, then exp(x) < minpos and the result will be either 0
    680  1.1       mrg    *      or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD,
    681  1.1       mrg    *      but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow
    682  1.1       mrg    *      after rounding in an unbounded exponent range). If -a < eps < -b,
    683  1.1       mrg    *        minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2).
    684  1.1       mrg    *      - If eps > -2^(-p), no underflow in MPFR_RNDU.
    685  1.1       mrg    *      - If eps > -2^(-p-1), no underflow in MPFR_RNDN.
    686  1.1       mrg    *      - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN.
    687  1.1       mrg    *      - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU.
    688  1.1       mrg    *      - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e.
    689  1.1       mrg    *        - log(2) < eps < ...
    690  1.1       mrg    *
    691  1.1       mrg    * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take
    692  1.1       mrg    * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need
    693  1.1       mrg    * to test mpfr_exp_3() too. This will be done via the e3 variable:
    694  1.1       mrg    *   e3 = 0: mpfr_exp(), thus mpfr_exp_2().
    695  1.1       mrg    *   e3 = 1: mpfr_exp_3(), via the exp_3() wrapper.
    696  1.1       mrg    * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd);
    697  1.1       mrg    */
    698  1.1       mrg 
    699  1.1       mrg   /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine:
    700  1.1       mrg    *   Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin
    701  1.1       mrg    *   for precx = 96, precy = 16, mpfr_exp_3
    702  1.1       mrg    *   Got 9 instead of 8.
    703  1.1       mrg    * Note: testing this case in several precisions for x and y introduces
    704  1.1       mrg    * some useful random. Indeed, the bug is not always triggered.
    705  1.1       mrg    * Fixed in r5469.
    706  1.1       mrg    */
    707  1.1       mrg   for (precx = 16; precx <= 128; precx += 16)
    708  1.1       mrg     {
    709  1.1       mrg       mpfr_init2 (x, precx);
    710  1.1       mrg       mpfr_log (x, minpos, MPFR_RNDU);
    711  1.1       mrg       for (precy = 16; precy <= 128; precy += 16)
    712  1.1       mrg         {
    713  1.1       mrg           mpfr_init2 (y, precy);
    714  1.1       mrg 
    715  1.1       mrg           for (e3 = 0; e3 <= 1; e3++)
    716  1.1       mrg             {
    717  1.1       mrg               RND_LOOP (rnd)
    718  1.1       mrg                 {
    719  1.1       mrg                   int err = 0;
    720  1.1       mrg 
    721  1.1       mrg                   mpfr_clear_flags ();
    722  1.1       mrg                   inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
    723  1.1       mrg                     : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
    724  1.5       mrg                   /* for MPFR_RNDF, the inexact flag is undefined */
    725  1.5       mrg                   if (__gmpfr_flags != MPFR_FLAGS_INEXACT && rnd != MPFR_RNDF)
    726  1.1       mrg                     {
    727  1.1       mrg                       printf ("Incorrect flags in underflow_up, eps > 0, %s",
    728  1.1       mrg                               mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    729  1.1       mrg                       if (extended_emin)
    730  1.1       mrg                         printf (" and extended emin");
    731  1.1       mrg                       printf ("\nfor precx = %d, precy = %d, %s\n",
    732  1.1       mrg                               precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
    733  1.5       mrg                       printf ("x="); mpfr_dump (x);
    734  1.5       mrg                       printf ("y="); mpfr_dump (y);
    735  1.5       mrg                       printf ("Got %u instead of %u.\n",
    736  1.5       mrg                               (unsigned int) __gmpfr_flags,
    737  1.1       mrg                               (unsigned int) MPFR_FLAGS_INEXACT);
    738  1.1       mrg                       err = 1;
    739  1.1       mrg                     }
    740  1.1       mrg                   if (mpfr_cmp0 (y, minpos) < 0)
    741  1.1       mrg                     {
    742  1.1       mrg                       printf ("Incorrect result in underflow_up, eps > 0, %s",
    743  1.1       mrg                               mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    744  1.1       mrg                       if (extended_emin)
    745  1.1       mrg                         printf (" and extended emin");
    746  1.1       mrg                       printf ("\nfor precx = %d, precy = %d, %s\n",
    747  1.1       mrg                               precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
    748  1.1       mrg                       mpfr_dump (y);
    749  1.1       mrg                       err = 1;
    750  1.1       mrg                     }
    751  1.5       mrg                   /* for MPFR_RNDF, the ternary value is undefined */
    752  1.5       mrg                   if (rnd != MPFR_RNDF)
    753  1.5       mrg                     MPFR_ASSERTN (inex != 0);
    754  1.1       mrg                   if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ)
    755  1.1       mrg                     MPFR_ASSERTN (inex < 0);
    756  1.1       mrg                   if (rnd == MPFR_RNDU)
    757  1.1       mrg                     MPFR_ASSERTN (inex > 0);
    758  1.1       mrg                   if (err)
    759  1.1       mrg                     exit (1);
    760  1.1       mrg                 }
    761  1.1       mrg             }
    762  1.1       mrg 
    763  1.1       mrg           mpfr_clear (y);
    764  1.1       mrg         }
    765  1.1       mrg       mpfr_clear (x);
    766  1.1       mrg     }
    767  1.1       mrg 
    768  1.1       mrg   /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x;
    769  1.1       mrg    * only check the result and the ternary value.
    770  1.1       mrg    * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails
    771  1.1       mrg    * for precx = 65 and precy = 16, e.g.:
    772  1.1       mrg    *   exp_2.c:264:  assertion failed: ...
    773  1.1       mrg    * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is
    774  1.1       mrg    * fixed in r5453 by going to next Ziv's iteration.
    775  1.1       mrg    */
    776  1.1       mrg   for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8)
    777  1.1       mrg     {
    778  1.1       mrg       mpfr_init2 (x, precx);
    779  1.1       mrg       mpfr_log (x, minpos, MPFR_RNDD);  /* |ulp| <= 1/2 */
    780  1.1       mrg       for (precy = 16; precy <= 128; precy += 16)
    781  1.1       mrg         {
    782  1.1       mrg           mpfr_init2 (y, precy);
    783  1.1       mrg           inex = mpfr_exp (y, x, MPFR_RNDN);
    784  1.1       mrg           if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
    785  1.1       mrg             {
    786  1.1       mrg               printf ("Error in underflow_up, - log(2) < eps < 0");
    787  1.1       mrg               if (extended_emin)
    788  1.1       mrg                 printf (" and extended emin");
    789  1.1       mrg               printf (" for prec = %d\nExpected ", precy);
    790  1.1       mrg               mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
    791  1.1       mrg               printf (" (minimum positive MPFR number) and inex > 0\nGot ");
    792  1.1       mrg               mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
    793  1.1       mrg               printf ("\nwith inex = %d\n", inex);
    794  1.1       mrg               exit (1);
    795  1.1       mrg             }
    796  1.1       mrg           mpfr_clear (y);
    797  1.1       mrg         }
    798  1.1       mrg       mpfr_clear (x);
    799  1.1       mrg     }
    800  1.1       mrg 
    801  1.1       mrg   /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely,
    802  1.1       mrg    *   _ for j = 0, eps > -2^(-(p+i)),
    803  1.1       mrg    *   _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))),
    804  1.1       mrg    * where i = 0 or 1.
    805  1.1       mrg    */
    806  1.1       mrg   mpfr_inits2 (2, t, t2, (mpfr_ptr) 0);
    807  1.1       mrg   for (precy = 16; precy <= 128; precy += 16)
    808  1.1       mrg     {
    809  1.1       mrg       mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN);         /* 2^(-p) */
    810  1.1       mrg       mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN);  /* 2^(-2p+1) */
    811  1.1       mrg       precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8;
    812  1.1       mrg       mpfr_init2 (x, precx);
    813  1.1       mrg       mpfr_init2 (y, precy);
    814  1.1       mrg       for (i = 0; i <= 1; i++)
    815  1.1       mrg         {
    816  1.1       mrg           for (j = 0; j <= 1; j++)
    817  1.1       mrg             {
    818  1.1       mrg               if (j == 0)
    819  1.1       mrg                 {
    820  1.1       mrg                   /* Case eps > -2^(-(p+i)). */
    821  1.1       mrg                   mpfr_log (x, minpos, MPFR_RNDU);
    822  1.1       mrg                 }
    823  1.1       mrg               else  /* j == 1 */
    824  1.1       mrg                 {
    825  1.1       mrg                   /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */
    826  1.1       mrg                   mpfr_log (x, minpos, MPFR_RNDD);
    827  1.1       mrg                   inex = mpfr_sub (x, x, t2, MPFR_RNDN);
    828  1.1       mrg                   MPFR_ASSERTN (inex == 0);
    829  1.1       mrg                 }
    830  1.1       mrg               inex = mpfr_sub (x, x, t, MPFR_RNDN);
    831  1.1       mrg               MPFR_ASSERTN (inex == 0);
    832  1.1       mrg 
    833  1.1       mrg               RND_LOOP (rnd)
    834  1.1       mrg                 for (e3 = 0; e3 <= 1; e3++)
    835  1.1       mrg                   {
    836  1.1       mrg                     int err = 0;
    837  1.1       mrg                     unsigned int flags;
    838  1.1       mrg 
    839  1.1       mrg                     flags = MPFR_FLAGS_INEXACT |
    840  1.1       mrg                       (((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
    841  1.1       mrg                              && (i == 1 || j == 0)) ||
    842  1.1       mrg                        (rnd == MPFR_RNDN && (i == 1 && j == 0)) ?
    843  1.1       mrg                        0 : MPFR_FLAGS_UNDERFLOW);
    844  1.1       mrg                     mpfr_clear_flags ();
    845  1.1       mrg                     inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
    846  1.1       mrg                       : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
    847  1.1       mrg                     if (__gmpfr_flags != flags)
    848  1.1       mrg                       {
    849  1.1       mrg                         printf ("Incorrect flags in underflow_up, %s",
    850  1.1       mrg                                 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    851  1.1       mrg                         if (extended_emin)
    852  1.1       mrg                           printf (" and extended emin");
    853  1.1       mrg                         printf ("\nfor precx = %d, precy = %d, ",
    854  1.1       mrg                                 precx, precy);
    855  1.1       mrg                         if (j == 0)
    856  1.1       mrg                           printf ("eps >~ -2^(-%d)", precy + i);
    857  1.1       mrg                         else
    858  1.1       mrg                           printf ("eps <~ - (2^(-%d) + 2^(%d))",
    859  1.1       mrg                                   precy + i, 1 - 2 * (precy + i));
    860  1.1       mrg                         printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
    861  1.1       mrg                         printf ("Got %u instead of %u.\n",
    862  1.5       mrg                                 (unsigned int) __gmpfr_flags, flags);
    863  1.1       mrg                         err = 1;
    864  1.1       mrg                       }
    865  1.5       mrg                     if (rnd == MPFR_RNDF)
    866  1.5       mrg                       continue; /* the test below makes no sense, since RNDF
    867  1.5       mrg                                    does not give a deterministic result */
    868  1.1       mrg                     if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ?
    869  1.1       mrg                         mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y))
    870  1.1       mrg                       {
    871  1.1       mrg                         printf ("Incorrect result in underflow_up, %s",
    872  1.1       mrg                                 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    873  1.1       mrg                         if (extended_emin)
    874  1.1       mrg                           printf (" and extended emin");
    875  1.1       mrg                         printf ("\nfor precx = %d, precy = %d, ",
    876  1.1       mrg                                 precx, precy);
    877  1.1       mrg                         if (j == 0)
    878  1.1       mrg                           printf ("eps >~ -2^(-%d)", precy + i);
    879  1.1       mrg                         else
    880  1.1       mrg                           printf ("eps <~ - (2^(-%d) + 2^(%d))",
    881  1.1       mrg                                   precy + i, 1 - 2 * (precy + i));
    882  1.1       mrg                         printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
    883  1.1       mrg                         mpfr_dump (y);
    884  1.1       mrg                         err = 1;
    885  1.1       mrg                       }
    886  1.1       mrg                     if (err)
    887  1.1       mrg                       exit (1);
    888  1.1       mrg                   }  /* for (e3 ...) */
    889  1.1       mrg             }  /* for (j ...) */
    890  1.1       mrg           mpfr_div_2si (t, t, 1, MPFR_RNDN);
    891  1.1       mrg           mpfr_div_2si (t2, t2, 2, MPFR_RNDN);
    892  1.1       mrg         }  /* for (i ...) */
    893  1.1       mrg       mpfr_clears (x, y, (mpfr_ptr) 0);
    894  1.1       mrg     }  /* for (precy ...) */
    895  1.1       mrg   mpfr_clears (t, t2, (mpfr_ptr) 0);
    896  1.1       mrg 
    897  1.1       mrg   /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2).
    898  1.1       mrg    * We choose x0 and x1 with high enough precision such that:
    899  1.1       mrg    *   x0 = rndd(rndd(log(minpos)) - rndu(log(2)))
    900  1.1       mrg    *   x1 = rndu(rndu(log(minpos)) - rndd(log(2)))
    901  1.1       mrg    * In revision 5507 (trunk) on a 64-bit Linux machine, this fails:
    902  1.1       mrg    *   Error in underflow_up, eps >~ - log(2) and extended emin
    903  1.1       mrg    *   for precy = 16, mpfr_exp
    904  1.1       mrg    *   Expected 1.0@-1152921504606846976 (minimum positive MPFR number),
    905  1.1       mrg    *   inex > 0 and flags = 9
    906  1.1       mrg    *   Got 0
    907  1.1       mrg    *   with inex = -1 and flags = 9
    908  1.1       mrg    * due to a double-rounding problem in mpfr_mul_2si when rescaling
    909  1.1       mrg    * the result.
    910  1.1       mrg    */
    911  1.1       mrg   mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0);
    912  1.1       mrg   for (i = 0; i <= 1; i++)
    913  1.1       mrg     {
    914  1.1       mrg       mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD);
    915  1.1       mrg       mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU);
    916  1.1       mrg       mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD);
    917  1.1       mrg       for (precy = 16; precy <= 128; precy += 16)
    918  1.1       mrg         {
    919  1.1       mrg           mpfr_init2 (y, precy);
    920  1.1       mrg           for (e3 = 0; e3 <= 1; e3++)
    921  1.1       mrg             {
    922  1.1       mrg               unsigned int flags, uflags =
    923  1.1       mrg                 MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
    924  1.1       mrg 
    925  1.1       mrg               mpfr_clear_flags ();
    926  1.1       mrg               inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN);
    927  1.1       mrg               flags = __gmpfr_flags;
    928  1.1       mrg               if (flags != uflags ||
    929  1.1       mrg                   (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
    930  1.1       mrg                      : (inex >= 0 || MPFR_NOTZERO (y))))
    931  1.1       mrg                 {
    932  1.1       mrg                   printf ("Error in underflow_up, eps %c~ - log(2)",
    933  1.1       mrg                           i ? '>' : '<');
    934  1.1       mrg                   if (extended_emin)
    935  1.1       mrg                     printf (" and extended emin");
    936  1.1       mrg                   printf ("\nfor precy = %d, %s\nExpected ", precy,
    937  1.1       mrg                           e3 ? "mpfr_exp_3" : "mpfr_exp");
    938  1.1       mrg                   if (i)
    939  1.1       mrg                     {
    940  1.1       mrg                       mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
    941  1.1       mrg                       printf (" (minimum positive MPFR number),\ninex >");
    942  1.1       mrg                     }
    943  1.1       mrg                   else
    944  1.1       mrg                     {
    945  1.1       mrg                       printf ("+0, inex <");
    946  1.1       mrg                     }
    947  1.1       mrg                   printf (" 0 and flags = %u\nGot ", uflags);
    948  1.1       mrg                   mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
    949  1.1       mrg                   printf ("\nwith inex = %d and flags = %u\n", inex, flags);
    950  1.1       mrg                   exit (1);
    951  1.1       mrg                 }
    952  1.1       mrg             }
    953  1.1       mrg           mpfr_clear (y);
    954  1.1       mrg         }
    955  1.1       mrg     }
    956  1.1       mrg   mpfr_clears (x, t, (mpfr_ptr) 0);
    957  1.1       mrg 
    958  1.1       mrg   mpfr_clear (minpos);
    959  1.1       mrg }
    960  1.1       mrg 
    961  1.1       mrg static void
    962  1.1       mrg underflow (void)
    963  1.1       mrg {
    964  1.1       mrg   mpfr_exp_t emin;
    965  1.1       mrg 
    966  1.1       mrg   underflow_up (0);
    967  1.1       mrg 
    968  1.1       mrg   emin = mpfr_get_emin ();
    969  1.1       mrg   set_emin (MPFR_EMIN_MIN);
    970  1.1       mrg   if (mpfr_get_emin () != emin)
    971  1.1       mrg     {
    972  1.1       mrg       underflow_up (1);
    973  1.1       mrg       set_emin (emin);
    974  1.1       mrg     }
    975  1.1       mrg }
    976  1.1       mrg 
    977  1.5       mrg /* bug found with GMP_CHECK_RANDOMIZE=1514290185 */
    978  1.5       mrg static void
    979  1.5       mrg bug20171223 (void)
    980  1.5       mrg {
    981  1.5       mrg   mpfr_t x, y;
    982  1.5       mrg   int inex;
    983  1.5       mrg 
    984  1.5       mrg   mpfr_init2 (x, 372);
    985  1.5       mrg   mpfr_init2 (y, 2);
    986  1.5       mrg   mpfr_set_str (x, "-6.9314716128384587678466323621915206417385796077947874471662159283492445979241549847386366371775938082803907383582e-01", 10, MPFR_RNDN);
    987  1.5       mrg   /* exp(x) = 0.500000009638..., should be rounded to 0.5 */
    988  1.5       mrg   inex = mpfr_exp (y, x, MPFR_RNDD);
    989  1.5       mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, -1) == 0);
    990  1.5       mrg   MPFR_ASSERTN(inex < 0);
    991  1.5       mrg   mpfr_clear (x);
    992  1.5       mrg   mpfr_clear (y);
    993  1.5       mrg }
    994  1.5       mrg 
    995  1.1       mrg int
    996  1.1       mrg main (int argc, char *argv[])
    997  1.1       mrg {
    998  1.1       mrg   tests_start_mpfr ();
    999  1.1       mrg 
   1000  1.1       mrg   if (argc > 1)
   1001  1.1       mrg     check_large ();
   1002  1.1       mrg 
   1003  1.5       mrg   bug20171223 ();
   1004  1.5       mrg 
   1005  1.1       mrg   check_inexact ();
   1006  1.1       mrg   check_special ();
   1007  1.1       mrg 
   1008  1.5       mrg   test_generic (MPFR_PREC_MIN, 100, 100);
   1009  1.1       mrg 
   1010  1.1       mrg   compare_exp2_exp3 (20, 1000);
   1011  1.1       mrg   check_worst_cases();
   1012  1.1       mrg   check3("0.0", MPFR_RNDU, "1.0");
   1013  1.1       mrg   check3("-1e-170", MPFR_RNDU, "1.0");
   1014  1.1       mrg   check3("-1e-170", MPFR_RNDN, "1.0");
   1015  1.1       mrg   check3("-8.88024741073346941839e-17", MPFR_RNDU, "1.0");
   1016  1.1       mrg   check3("8.70772839244701057915e-01", MPFR_RNDN, "2.38875626491680437269");
   1017  1.1       mrg   check3("1.0", MPFR_RNDN, "2.71828182845904509080");
   1018  1.1       mrg   check3("-3.42135637628104173534e-07", MPFR_RNDZ, "0.999999657864420798958");
   1019  1.1       mrg   /* worst case for argument reduction, very near from 5*log(2),
   1020  1.1       mrg      thanks to Jean-Michel Muller  */
   1021  1.1       mrg   check3("3.4657359027997265421", MPFR_RNDN, "32.0");
   1022  1.1       mrg   check3("3.4657359027997265421", MPFR_RNDU, "32.0");
   1023  1.1       mrg   check3("3.4657359027997265421", MPFR_RNDD, "31.999999999999996447");
   1024  1.1       mrg   check3("2.26523754332090625496e+01", MPFR_RNDD, "6.8833785261699581146e9");
   1025  1.1       mrg   check3("1.31478962104089092122e+01", MPFR_RNDZ, "5.12930793917860137299e+05");
   1026  1.1       mrg   check3("4.25637507920002378103e-01", MPFR_RNDU, "1.53056585656161181497e+00");
   1027  1.1       mrg   check3("6.26551618962329307459e-16", MPFR_RNDU, "1.00000000000000066613e+00");
   1028  1.1       mrg   check3("-3.35589513871216568383e-03",MPFR_RNDD, "9.96649729583626853291e-01");
   1029  1.1       mrg   check3("1.95151388850007272424e+01", MPFR_RNDU, "2.98756340674767792225e+08");
   1030  1.1       mrg   check3("2.45045953503350730784e+01", MPFR_RNDN, "4.38743344916128387451e+10");
   1031  1.1       mrg   check3("2.58165606081678085104e+01", MPFR_RNDD, "1.62925781879432281494e+11");
   1032  1.1       mrg   check3("-2.36539020084338638128e+01",MPFR_RNDZ, "5.33630792749924762447e-11");
   1033  1.1       mrg   check3("2.39211946135858077866e+01", MPFR_RNDU, "2.44817704330214385986e+10");
   1034  1.1       mrg   check3("-2.78190533055889162029e+01",MPFR_RNDZ, "8.2858803483596879512e-13");
   1035  1.1       mrg   check3("2.64028186174889789584e+01", MPFR_RNDD, "2.9281844652878973388e11");
   1036  1.1       mrg   check3("2.92086338843268329413e+01", MPFR_RNDZ, "4.8433797301907177734e12");
   1037  1.1       mrg   check3("-2.46355324071459982349e+01",MPFR_RNDZ, "1.9995129297760994791e-11");
   1038  1.1       mrg   check3("-2.23509444608605427618e+01",MPFR_RNDZ, "1.9638492867489702307e-10");
   1039  1.1       mrg   check3("-2.41175390197331687148e+01",MPFR_RNDD, "3.3564940885530624592e-11");
   1040  1.1       mrg   check3("2.46363885231578088053e+01", MPFR_RNDU, "5.0055014282693267822e10");
   1041  1.1       mrg   check3("111.1263531080090984914932050742208957672119140625", MPFR_RNDN, "1.8262572323517295459e48");
   1042  1.1       mrg   check3("-3.56196340354684821250e+02",MPFR_RNDN, "2.0225297096141478156e-155");
   1043  1.1       mrg   check3("6.59678273772710895173e+02", MPFR_RNDU, "3.1234469273830195529e286");
   1044  1.1       mrg   check3("5.13772529701934331570e+02", MPFR_RNDD, "1.3445427121297197752e223");
   1045  1.1       mrg   check3("3.57430211008718345056e+02", MPFR_RNDD, "1.6981197246857298443e155");
   1046  1.1       mrg   check3("3.82001814471465536371e+02", MPFR_RNDU, "7.9667300591087367805e165");
   1047  1.1       mrg   check3("5.92396038219384422518e+02", MPFR_RNDD, "1.880747529554661989e257");
   1048  1.1       mrg   check3("-5.02678550462488090034e+02",MPFR_RNDU, "4.8919201895446217839e-219");
   1049  1.1       mrg   check3("5.30015757134837031117e+02", MPFR_RNDD, "1.5237672861171573939e230");
   1050  1.1       mrg   check3("5.16239362447650933063e+02", MPFR_RNDZ, "1.5845518406744492105e224");
   1051  1.1       mrg   check3("6.00812634798592370977e-01", MPFR_RNDN, "1.823600119339019443");
   1052  1.1       mrg   check_exp10 ();
   1053  1.1       mrg 
   1054  1.1       mrg   bug20080731 ();
   1055  1.1       mrg 
   1056  1.1       mrg   overflowed_exp0 ();
   1057  1.1       mrg   underflow ();
   1058  1.1       mrg 
   1059  1.1       mrg   data_check ("data/exp", mpfr_exp, "mpfr_exp");
   1060  1.1       mrg   bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50);
   1061  1.1       mrg 
   1062  1.1       mrg   tests_end_mpfr ();
   1063  1.1       mrg   return 0;
   1064  1.1       mrg }
   1065