(root)/
mpfr-4.2.1/
tests/
tgeneric_ui.c
       1  /* Generic test file for functions with one mpfr_t argument and an integer.
       2  
       3  Copyright 2005-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  /* define INTEGER_TYPE to what we want */
      24  #ifndef INTEGER_TYPE
      25  # define INTEGER_TYPE mp_limb_t
      26  #endif
      27  #ifndef RAND_FUNCTION
      28  # define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS)
      29  #endif
      30  #ifndef INT_RAND_FUNCTION
      31  # define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb ()
      32  #endif
      33  
      34  static void
      35  test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
      36  {
      37    mpfr_prec_t prec, yprec;
      38    mpfr_t x, y, z, t;
      39    INTEGER_TYPE u;
      40    mpfr_rnd_t rnd;
      41    int inexact, compare, compare2;
      42    unsigned int n;
      43  
      44    mpfr_init (x);
      45    mpfr_init (y);
      46    mpfr_init (z);
      47    mpfr_init (t);
      48  
      49    /* generic test */
      50    for (prec = p0; prec <= p1; prec++)
      51      {
      52        mpfr_set_prec (x, prec);
      53        mpfr_set_prec (z, prec);
      54        mpfr_set_prec (t, prec);
      55        yprec = prec + 10;
      56  
      57        for (n = 0; n <= N; n++)
      58          {
      59            if (n > 1 || prec < p1)
      60              RAND_FUNCTION (x);
      61            else
      62              {
      63                /* Special cases tested in precision p1 if n <= 1. */
      64                mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
      65                mpfr_set_exp (x, mpfr_get_emin ());
      66              }
      67            if (n < 2 || n > 3 || prec < p1)
      68              u = INT_RAND_FUNCTION ();
      69            else
      70              {
      71                /* Special cases tested in precision p1 if n = 2 or 3. */
      72                if ((INTEGER_TYPE) -1 < 0)  /* signed, type long assumed */
      73                  u = n == 2 ? LONG_MIN : LONG_MAX;
      74                else  /* unsigned */
      75                  u = n == 2 ? 0 : -1;
      76              }
      77            rnd = RND_RAND_NO_RNDF ();
      78            mpfr_set_prec (y, yprec);
      79            compare = TEST_FUNCTION (y, x, u, rnd);
      80            if (mpfr_can_round (y, yprec, rnd, rnd, prec))
      81              {
      82                mpfr_set (t, y, rnd);
      83                inexact = TEST_FUNCTION (z, x, u, rnd);
      84                if (mpfr_cmp (t, z))
      85                  {
      86                    printf ("results differ for x=");
      87                    mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
      88                    printf ("\nu=%lu", (unsigned long) u);
      89                    printf (" prec=%lu rnd_mode=%s\n",
      90                            (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
      91  #ifdef TEST_FUNCTION_NAME
      92                    printf ("Function: %s\n", TEST_FUNCTION_NAME);
      93  #endif
      94                    printf ("got      ");
      95                    mpfr_dump (z);
      96                    printf ("expected ");
      97                    mpfr_dump (t);
      98                    printf ("approx   ");
      99                    mpfr_dump (y);
     100                    exit (1);
     101                  }
     102                compare2 = mpfr_cmp (t, y);
     103                /* if rounding to nearest, cannot know the sign of t - f(x)
     104                   because of composed rounding: y = o(f(x)) and t = o(y) */
     105                if (compare * compare2 >= 0)
     106                  compare = compare + compare2;
     107                else
     108                  compare = inexact; /* cannot determine sign(t-f(x)) */
     109                if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF)
     110                  {
     111                    printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
     112                            "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
     113                    printf ("x = "); mpfr_dump (x);
     114                    printf ("u = %lu\n", (unsigned long) u);
     115                    printf ("y = "); mpfr_dump (y);
     116                    printf ("t = "); mpfr_dump (t);
     117                    exit (1);
     118                  }
     119              }
     120          }
     121      }
     122  
     123    mpfr_clear (x);
     124    mpfr_clear (y);
     125    mpfr_clear (z);
     126    mpfr_clear (t);
     127  }
     128  
     129  #undef RAND_FUNCTION
     130  #undef INTEGER_TYPE
     131  #undef TEST_FUNCTION
     132  #undef TEST_FUNCTION_NAME
     133  #undef test_generic_ui
     134  #undef INT_RAND_FUNCTION