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