Home | History | Annotate | Line # | Download | only in tests
      1  1.1  mrg /* Test file for mpfr_exp2m1.
      2  1.1  mrg 
      3  1.1  mrg Copyright 2001-2023 Free Software Foundation, Inc.
      4  1.1  mrg Contributed by the AriC and Caramba projects, INRIA.
      5  1.1  mrg 
      6  1.1  mrg This file is part of the GNU MPFR Library.
      7  1.1  mrg 
      8  1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9  1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     10  1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     11  1.1  mrg option) any later version.
     12  1.1  mrg 
     13  1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15  1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16  1.1  mrg License for more details.
     17  1.1  mrg 
     18  1.1  mrg You should have received a copy of the GNU Lesser General Public License
     19  1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20  1.1  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 #define TEST_FUNCTION mpfr_exp2m1
     26  1.1  mrg #define TEST_RANDOM_EMIN -36
     27  1.1  mrg #define TEST_RANDOM_EMAX 36
     28  1.1  mrg #include "tgeneric.c"
     29  1.1  mrg 
     30  1.1  mrg static void
     31  1.1  mrg special (void)
     32  1.1  mrg {
     33  1.1  mrg   mpfr_t x, y;
     34  1.1  mrg   int i;
     35  1.1  mrg 
     36  1.1  mrg   mpfr_init2 (x, 2);
     37  1.1  mrg   mpfr_init2 (y, 2);
     38  1.1  mrg 
     39  1.1  mrg   mpfr_set_nan (x);
     40  1.1  mrg   mpfr_exp2m1 (y, x, MPFR_RNDN);
     41  1.1  mrg   if (!mpfr_nan_p (y))
     42  1.1  mrg     {
     43  1.1  mrg       printf ("Error for exp2m1(NaN)\n");
     44  1.1  mrg       exit (1);
     45  1.1  mrg     }
     46  1.1  mrg 
     47  1.1  mrg   mpfr_set_inf (x, 1);
     48  1.1  mrg   mpfr_exp2m1 (y, x, MPFR_RNDN);
     49  1.1  mrg   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
     50  1.1  mrg     {
     51  1.1  mrg       printf ("Error for exp2m1(+Inf)\n");
     52  1.1  mrg       exit (1);
     53  1.1  mrg     }
     54  1.1  mrg 
     55  1.1  mrg   mpfr_set_inf (x, -1);
     56  1.1  mrg   mpfr_exp2m1 (y, x, MPFR_RNDN);
     57  1.1  mrg   if (mpfr_cmp_si (y, -1) != 0)
     58  1.1  mrg     {
     59  1.1  mrg       printf ("Error for exp2m1(-Inf)\n");
     60  1.1  mrg       exit (1);
     61  1.1  mrg     }
     62  1.1  mrg 
     63  1.1  mrg   mpfr_set_ui (x, 0, MPFR_RNDN);
     64  1.1  mrg   mpfr_exp2m1 (y, x, MPFR_RNDN);
     65  1.1  mrg   if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
     66  1.1  mrg     {
     67  1.1  mrg       printf ("Error for exp2m1(+0)\n");
     68  1.1  mrg       exit (1);
     69  1.1  mrg     }
     70  1.1  mrg 
     71  1.1  mrg   mpfr_neg (x, x, MPFR_RNDN);
     72  1.1  mrg   mpfr_exp2m1 (y, x, MPFR_RNDN);
     73  1.1  mrg   if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
     74  1.1  mrg     {
     75  1.1  mrg       printf ("Error for exp2m1(-0)\n");
     76  1.1  mrg       exit (1);
     77  1.1  mrg     }
     78  1.1  mrg 
     79  1.1  mrg   /* Check overflow of exp2m1(x) */
     80  1.1  mrg   mpfr_clear_flags ();
     81  1.1  mrg   mpfr_set_str_binary (x, "1.1E1000000000");
     82  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDN);
     83  1.1  mrg   MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x));
     84  1.1  mrg   MPFR_ASSERTN (mpfr_overflow_p ());
     85  1.1  mrg   MPFR_ASSERTN (i > 0);
     86  1.1  mrg 
     87  1.1  mrg   mpfr_clear_flags ();
     88  1.1  mrg   mpfr_set_str_binary (x, "1.1E1000000000");
     89  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDU);
     90  1.1  mrg   MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x));
     91  1.1  mrg   MPFR_ASSERTN (mpfr_overflow_p ());
     92  1.1  mrg   MPFR_ASSERTN (i > 0);
     93  1.1  mrg 
     94  1.1  mrg   mpfr_clear_flags ();
     95  1.1  mrg   mpfr_set_str_binary (x, "1.1E1000000000");
     96  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDD);
     97  1.1  mrg   MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_IS_POS (x));
     98  1.1  mrg   MPFR_ASSERTN (mpfr_overflow_p ());
     99  1.1  mrg   MPFR_ASSERTN (i < 0);
    100  1.1  mrg 
    101  1.1  mrg   /* Check internal underflow of exp2m1 (x) */
    102  1.1  mrg   mpfr_set_prec (x, 2);
    103  1.1  mrg   mpfr_clear_flags ();
    104  1.1  mrg   mpfr_set_str_binary (x, "-1.1E1000000000");
    105  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDN);
    106  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
    107  1.1  mrg   MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
    108  1.1  mrg   MPFR_ASSERTN (i < 0);
    109  1.1  mrg 
    110  1.1  mrg   mpfr_set_str_binary (x, "-1.1E1000000000");
    111  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDD);
    112  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
    113  1.1  mrg   MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
    114  1.1  mrg   MPFR_ASSERTN (i < 0);
    115  1.1  mrg 
    116  1.1  mrg   mpfr_set_str_binary (x, "-1.1E1000000000");
    117  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDZ);
    118  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
    119  1.1  mrg   MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
    120  1.1  mrg   MPFR_ASSERTN (i > 0);
    121  1.1  mrg 
    122  1.1  mrg   mpfr_set_str_binary (x, "-1.1E1000000000");
    123  1.1  mrg   i = mpfr_exp2m1 (x, x, MPFR_RNDU);
    124  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
    125  1.1  mrg   MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
    126  1.1  mrg   MPFR_ASSERTN (i > 0);
    127  1.1  mrg 
    128  1.1  mrg   /* hard-coded test */
    129  1.1  mrg   mpfr_set_prec (x, 32);
    130  1.1  mrg   mpfr_set_prec (y, 32);
    131  1.1  mrg   mpfr_set_ui_2exp (x, 1686629713UL, -29, MPFR_RNDN); /* approximates Pi */
    132  1.1  mrg   i = mpfr_exp2m1 (y, x, MPFR_RNDN);
    133  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_ui_2exp (y, 2100501491UL, -28) == 0);
    134  1.1  mrg   MPFR_ASSERTN (i < 0);
    135  1.1  mrg 
    136  1.1  mrg   mpfr_clear (x);
    137  1.1  mrg   mpfr_clear (y);
    138  1.1  mrg }
    139  1.1  mrg 
    140  1.1  mrg /* test integer x, -100 <= x <= 100, where 2^x-1 is exact */
    141  1.1  mrg static void
    142  1.1  mrg test_exact (void)
    143  1.1  mrg {
    144  1.1  mrg   long k;
    145  1.1  mrg   mpfr_t x, y, z;
    146  1.1  mrg   mpz_t n;
    147  1.1  mrg   mpfr_prec_t p;
    148  1.1  mrg   int i, j, r;
    149  1.1  mrg 
    150  1.1  mrg   mpfr_init2 (x, 7); /* 100 is exact within 7 bits */
    151  1.1  mrg   mpfr_init2 (y, MPFR_PREC_MIN);
    152  1.1  mrg   mpfr_init2 (z, MPFR_PREC_MIN);
    153  1.1  mrg   mpz_init_set_ui (n, 1);
    154  1.1  mrg   for (k = 1; k <= 100; k++)
    155  1.1  mrg     {
    156  1.1  mrg       /* invariant: n = 2^k-1 */
    157  1.1  mrg       for (p = MPFR_PREC_MIN; p <= 100; p++)
    158  1.1  mrg         {
    159  1.1  mrg           mpfr_set_prec (y, p);
    160  1.1  mrg           mpfr_set_prec (z, p);
    161  1.1  mrg           mpfr_set_si (x, k, MPFR_RNDN);
    162  1.1  mrg           /* for RNDF, result may differ */
    163  1.1  mrg           RND_LOOP_NO_RNDF(r)
    164  1.1  mrg             {
    165  1.1  mrg               i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r);
    166  1.1  mrg               j = mpfr_set_z (z, n, (mpfr_rnd_t) r);
    167  1.1  mrg               if (!mpfr_equal_p (y, z))
    168  1.1  mrg                 {
    169  1.1  mrg                   printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", k,
    170  1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    171  1.1  mrg                   printf ("expected "); mpfr_dump (z);
    172  1.1  mrg                   printf ("got      "); mpfr_dump (y);
    173  1.1  mrg                   exit (1);
    174  1.1  mrg                 }
    175  1.1  mrg               if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0))
    176  1.1  mrg                 {
    177  1.1  mrg                   printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n",
    178  1.1  mrg                           k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    179  1.1  mrg                   printf ("expected %d\n", j);
    180  1.1  mrg                   printf ("got      %d\n", i);
    181  1.1  mrg                   exit (1);
    182  1.1  mrg                 }
    183  1.1  mrg             }
    184  1.1  mrg           mpfr_set_si (x, -k, MPFR_RNDN);
    185  1.1  mrg           /* 1/2^k-1 = (1-2^k)/2^k = -n/2^k */
    186  1.1  mrg           RND_LOOP_NO_RNDF(r)
    187  1.1  mrg             {
    188  1.1  mrg               i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r);
    189  1.1  mrg               j = mpfr_set_z (z, n, MPFR_INVERT_RND((mpfr_rnd_t) r));
    190  1.1  mrg               mpfr_neg (z, z, (mpfr_rnd_t) r);
    191  1.1  mrg               j = -j;
    192  1.1  mrg               mpfr_div_2ui (z, z, k, (mpfr_rnd_t) r);
    193  1.1  mrg               if (!mpfr_equal_p (y, z))
    194  1.1  mrg                 {
    195  1.1  mrg                   printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", -k,
    196  1.1  mrg                           mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    197  1.1  mrg                   printf ("expected "); mpfr_dump (z);
    198  1.1  mrg                   printf ("got      "); mpfr_dump (y);
    199  1.1  mrg                   exit (1);
    200  1.1  mrg                 }
    201  1.1  mrg               if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0))
    202  1.1  mrg                 {
    203  1.1  mrg                   printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n",
    204  1.1  mrg                           -k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    205  1.1  mrg                   printf ("expected %d\n", j);
    206  1.1  mrg                   printf ("got      %d\n", i);
    207  1.1  mrg                   exit (1);
    208  1.1  mrg                 }
    209  1.1  mrg             }
    210  1.1  mrg         }
    211  1.1  mrg       mpz_mul_2exp (n, n, 1);
    212  1.1  mrg       mpz_add_ui (n, n, 1);
    213  1.1  mrg     }
    214  1.1  mrg   mpfr_clear (x);
    215  1.1  mrg   mpfr_clear (y);
    216  1.1  mrg   mpfr_clear (z);
    217  1.1  mrg   mpz_clear (n);
    218  1.1  mrg }
    219  1.1  mrg 
    220  1.1  mrg int
    221  1.1  mrg main (int argc, char *argv[])
    222  1.1  mrg {
    223  1.1  mrg   tests_start_mpfr ();
    224  1.1  mrg 
    225  1.1  mrg   special ();
    226  1.1  mrg 
    227  1.1  mrg   test_exact ();
    228  1.1  mrg 
    229  1.1  mrg   test_generic (MPFR_PREC_MIN, 100, 100);
    230  1.1  mrg 
    231  1.1  mrg   tests_end_mpfr ();
    232  1.1  mrg   return 0;
    233  1.1  mrg }
    234