xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/trootn_si.c (revision ba125506a622fe649968631a56eba5d42ff57863)
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
special(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
main(void)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 }
225