(root)/
mpfr-4.2.1/
tests/
trootn_si.c
       1  /* Test file for mpfr_rootn_si.
       2  
       3  Copyright 2022-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  #include "mpfr-test.h"
      24  
      25  #define DEFN(N)                                                         \
      26    static int root##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)        \
      27    { return mpfr_rootn_si (y, x, N, rnd); }                              \
      28    static int pow##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)         \
      29    { return mpfr_pow_si (y, x, N, rnd); }                                \
      30    static int rootm##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)       \
      31    { return mpfr_rootn_si (y, x, -N, rnd); }                             \
      32    static int powm##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)        \
      33    { return mpfr_pow_si (y, x, -N, rnd); }
      34  
      35  DEFN(2)
      36  DEFN(3)
      37  DEFN(4)
      38  DEFN(5)
      39  DEFN(17)
      40  DEFN(120)
      41  
      42  static void
      43  special (void)
      44  {
      45    mpfr_t x, y;
      46    int i, inex, sx;
      47    int n[] = { -123456, -12345, -123, -12, -5, -4, -3, -2, -1, 0,
      48      1, 2, 3, 4, 5, 12, 123, 12345, 123456 };
      49  
      50    mpfr_inits2 (123, x, y, (mpfr_ptr) 0);
      51  
      52    /* rootn(NaN) = NaN */
      53    mpfr_set_nan (x);
      54    for (i = 0; i < numberof (n); i++)
      55      {
      56        mpfr_clear_flags ();
      57        inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
      58        if (! MPFR_IS_NAN (y))
      59          {
      60            printf ("Error: rootn(NaN,%d) <> NaN\n", n[i]);
      61            exit (1);
      62          }
      63        MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
      64        MPFR_ASSERTN (inex == 0);
      65      }
      66  
      67    /* rootn(+Inf) = +0, NaN or +Inf for sign(n) = -1, 0, 1 respectively */
      68    mpfr_set_inf (x, 1);
      69    for (i = 0; i < numberof (n); i++)
      70      {
      71        mpfr_clear_flags ();
      72        inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
      73        if (n[i] < 0)
      74          {
      75            if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
      76              {
      77                printf ("Error: rootn(+Inf,%d) <> +0\n", n[i]);
      78                exit (1);
      79              }
      80          }
      81        else if (n[i] > 0)
      82          {
      83            if (! MPFR_IS_INF (y) || MPFR_IS_NEG (y))
      84              {
      85                printf ("Error: rootn(+Inf,%d) <> +Inf\n", n[i]);
      86                exit (1);
      87              }
      88          }
      89        else if (! MPFR_IS_NAN (y))
      90          {
      91            printf ("Error: rootn(+Inf,0) <> NaN\n");
      92            exit (1);
      93          }
      94        MPFR_ASSERTN (__gmpfr_flags == (n[i] == 0 ? MPFR_FLAGS_NAN : 0));
      95        MPFR_ASSERTN (inex == 0);
      96      }
      97  
      98    /* rootn(-Inf) = -0 (resp. -Inf) for sign(n) = -1 (resp. 1) and odd n,
      99       NaN for even n */
     100    mpfr_set_inf (x, -1);
     101    for (i = 0; i < numberof (n); i++)
     102      {
     103        mpfr_clear_flags ();
     104        inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
     105        if (n[i] % 2 == 0)
     106          {
     107            if (! MPFR_IS_NAN (y))
     108              {
     109                printf ("Error: rootn(-Inf,%d) <> NaN\n", n[i]);
     110                exit (1);
     111              }
     112            MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
     113          }
     114        else
     115          {
     116            if (n[i] < 0)
     117              {
     118                if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
     119                  {
     120                    printf ("Error: rootn(-Inf,%d) <> -0\n", n[i]);
     121                    exit (1);
     122                  }
     123              }
     124            else
     125              {
     126                if (! MPFR_IS_INF (y) || MPFR_IS_POS (y))
     127                  {
     128                    printf ("Error: rootn(-Inf,%d) <> -Inf\n", n[i]);
     129                    exit (1);
     130                  }
     131              }
     132            MPFR_ASSERTN (__gmpfr_flags == 0);
     133          }
     134        MPFR_ASSERTN (inex == 0);
     135      }
     136  
     137    /* rootn(+/- 0) */
     138    for (i = 0; i < numberof (n); i++)
     139      for (sx = -1; sx <= 1; sx += 2)
     140        {
     141          mpfr_set_zero (x, sx);
     142          mpfr_clear_flags ();
     143          inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
     144          if (sx > 0 || n[i] % 2 == 0 ? MPFR_IS_NEG (y) : MPFR_IS_POS (y))
     145            {
     146              printf ("Error: rootn(%c0,%d) has a wrong sign\n",
     147                      sx > 0 ? '+' : '-', n[i]);
     148              exit (1);
     149            }
     150          if (n[i] < 0)
     151            {
     152              if (! MPFR_IS_INF (y))
     153                {
     154                  printf ("Error: rootn(%c0,%d) is not an infinity\n",
     155                          sx > 0 ? '+' : '-', n[i]);
     156                  exit (1);
     157                }
     158              MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
     159            }
     160          else if (n[i] > 0)
     161            {
     162              if (MPFR_NOTZERO (y))
     163                {
     164                  printf ("Error: rootn(%c0,%d) is not a zero\n",
     165                          sx > 0 ? '+' : '-', n[i]);
     166                  exit (1);
     167                }
     168              MPFR_ASSERTN (__gmpfr_flags == 0);
     169            }
     170          else
     171            {
     172              if (! MPFR_IS_NAN (y))
     173                {
     174                  printf ("Error: rootn(%c0,0) <> NaN\n", sx > 0 ? '+' : '-');
     175                  exit (1);
     176                }
     177              MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
     178            }
     179          MPFR_ASSERTN (inex == 0);
     180        }
     181  
     182    /* TODO: complete the tests. */
     183  
     184    mpfr_clears (x, y, (mpfr_ptr) 0);
     185  }
     186  
     187  #define TEST_FUNCTION mpfr_rootn_si
     188  #define INTEGER_TYPE long
     189  #define INT_RAND_FUNCTION() \
     190    (randlimb () % 16 == 0 ? randlong () : (long) (randlimb () % 31) - 15)
     191  #include "tgeneric_ui.c"
     192  
     193  int
     194  main (void)
     195  {
     196    tests_start_mpfr ();
     197  
     198    special ();
     199  
     200    /* The sign of the random value y (used to generate a potential bad case)
     201       is negative with a probability 256/512 = 1/2 for odd n, and never
     202       negative (probability 0/512) for even n (if y is negative, then
     203       (y^(2k))^(1/(2k)) is different from y, so that this would yield
     204       an error). */
     205    bad_cases (root2, pow2, "rootn[2]", 0, -256, 255, 4, 128, 80, 40);
     206    bad_cases (root3, pow3, "rootn[3]", 256, -256, 255, 4, 128, 200, 40);
     207    bad_cases (root4, pow4, "rootn[4]", 0, -256, 255, 4, 128, 320, 40);
     208    bad_cases (root5, pow5, "rootn[5]", 256, -256, 255, 4, 128, 440, 40);
     209    bad_cases (root17, pow17, "rootn[17]", 256, -256, 255, 4, 128, 800, 40);
     210    bad_cases (root120, pow120, "rootn[120]", 0, -256, 255, 4, 128, 800, 40);
     211  
     212    /* Ditto. */
     213    bad_cases (rootm2, powm2, "rootn[-2]", 0, -256, 255, 4, 128, 80, 40);
     214    bad_cases (rootm3, powm3, "rootn[-3]", 256, -256, 255, 4, 128, 200, 40);
     215    bad_cases (rootm4, powm4, "rootn[-4]", 0, -256, 255, 4, 128, 320, 40);
     216    bad_cases (rootm5, powm5, "rootn[-5]", 256, -256, 255, 4, 128, 440, 40);
     217    bad_cases (rootm17, powm17, "rootn[-17]", 256, -256, 255, 4, 128, 800, 40);
     218    bad_cases (rootm120, powm120, "rootn[-120]", 0, -256, 255, 4, 128, 800, 40);
     219  
     220    test_generic_ui (MPFR_PREC_MIN, 200, 30);
     221  
     222    tests_end_mpfr ();
     223    return 0;
     224  }