1*ba125506Smrg /* Test file for mpfr_rootn_si.
2*ba125506Smrg
3*ba125506Smrg Copyright 2022-2023 Free Software Foundation, Inc.
4*ba125506Smrg Contributed by the AriC and Caramba projects, INRIA.
5*ba125506Smrg
6*ba125506Smrg This file is part of the GNU MPFR Library.
7*ba125506Smrg
8*ba125506Smrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9*ba125506Smrg it under the terms of the GNU Lesser General Public License as published by
10*ba125506Smrg the Free Software Foundation; either version 3 of the License, or (at your
11*ba125506Smrg option) any later version.
12*ba125506Smrg
13*ba125506Smrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14*ba125506Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15*ba125506Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16*ba125506Smrg License for more details.
17*ba125506Smrg
18*ba125506Smrg You should have received a copy of the GNU Lesser General Public License
19*ba125506Smrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20*ba125506Smrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21*ba125506Smrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22*ba125506Smrg
23*ba125506Smrg #include "mpfr-test.h"
24*ba125506Smrg
25*ba125506Smrg #define DEFN(N) \
26*ba125506Smrg static int root##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
27*ba125506Smrg { return mpfr_rootn_si (y, x, N, rnd); } \
28*ba125506Smrg static int pow##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
29*ba125506Smrg { return mpfr_pow_si (y, x, N, rnd); } \
30*ba125506Smrg static int rootm##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
31*ba125506Smrg { return mpfr_rootn_si (y, x, -N, rnd); } \
32*ba125506Smrg static int powm##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
33*ba125506Smrg { return mpfr_pow_si (y, x, -N, rnd); }
34*ba125506Smrg
35*ba125506Smrg DEFN(2)
36*ba125506Smrg DEFN(3)
37*ba125506Smrg DEFN(4)
38*ba125506Smrg DEFN(5)
39*ba125506Smrg DEFN(17)
40*ba125506Smrg DEFN(120)
41*ba125506Smrg
42*ba125506Smrg static void
special(void)43*ba125506Smrg special (void)
44*ba125506Smrg {
45*ba125506Smrg mpfr_t x, y;
46*ba125506Smrg int i, inex, sx;
47*ba125506Smrg int n[] = { -123456, -12345, -123, -12, -5, -4, -3, -2, -1, 0,
48*ba125506Smrg 1, 2, 3, 4, 5, 12, 123, 12345, 123456 };
49*ba125506Smrg
50*ba125506Smrg mpfr_inits2 (123, x, y, (mpfr_ptr) 0);
51*ba125506Smrg
52*ba125506Smrg /* rootn(NaN) = NaN */
53*ba125506Smrg mpfr_set_nan (x);
54*ba125506Smrg for (i = 0; i < numberof (n); i++)
55*ba125506Smrg {
56*ba125506Smrg mpfr_clear_flags ();
57*ba125506Smrg inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
58*ba125506Smrg if (! MPFR_IS_NAN (y))
59*ba125506Smrg {
60*ba125506Smrg printf ("Error: rootn(NaN,%d) <> NaN\n", n[i]);
61*ba125506Smrg exit (1);
62*ba125506Smrg }
63*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
64*ba125506Smrg MPFR_ASSERTN (inex == 0);
65*ba125506Smrg }
66*ba125506Smrg
67*ba125506Smrg /* rootn(+Inf) = +0, NaN or +Inf for sign(n) = -1, 0, 1 respectively */
68*ba125506Smrg mpfr_set_inf (x, 1);
69*ba125506Smrg for (i = 0; i < numberof (n); i++)
70*ba125506Smrg {
71*ba125506Smrg mpfr_clear_flags ();
72*ba125506Smrg inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
73*ba125506Smrg if (n[i] < 0)
74*ba125506Smrg {
75*ba125506Smrg if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
76*ba125506Smrg {
77*ba125506Smrg printf ("Error: rootn(+Inf,%d) <> +0\n", n[i]);
78*ba125506Smrg exit (1);
79*ba125506Smrg }
80*ba125506Smrg }
81*ba125506Smrg else if (n[i] > 0)
82*ba125506Smrg {
83*ba125506Smrg if (! MPFR_IS_INF (y) || MPFR_IS_NEG (y))
84*ba125506Smrg {
85*ba125506Smrg printf ("Error: rootn(+Inf,%d) <> +Inf\n", n[i]);
86*ba125506Smrg exit (1);
87*ba125506Smrg }
88*ba125506Smrg }
89*ba125506Smrg else if (! MPFR_IS_NAN (y))
90*ba125506Smrg {
91*ba125506Smrg printf ("Error: rootn(+Inf,0) <> NaN\n");
92*ba125506Smrg exit (1);
93*ba125506Smrg }
94*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == (n[i] == 0 ? MPFR_FLAGS_NAN : 0));
95*ba125506Smrg MPFR_ASSERTN (inex == 0);
96*ba125506Smrg }
97*ba125506Smrg
98*ba125506Smrg /* rootn(-Inf) = -0 (resp. -Inf) for sign(n) = -1 (resp. 1) and odd n,
99*ba125506Smrg NaN for even n */
100*ba125506Smrg mpfr_set_inf (x, -1);
101*ba125506Smrg for (i = 0; i < numberof (n); i++)
102*ba125506Smrg {
103*ba125506Smrg mpfr_clear_flags ();
104*ba125506Smrg inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
105*ba125506Smrg if (n[i] % 2 == 0)
106*ba125506Smrg {
107*ba125506Smrg if (! MPFR_IS_NAN (y))
108*ba125506Smrg {
109*ba125506Smrg printf ("Error: rootn(-Inf,%d) <> NaN\n", n[i]);
110*ba125506Smrg exit (1);
111*ba125506Smrg }
112*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
113*ba125506Smrg }
114*ba125506Smrg else
115*ba125506Smrg {
116*ba125506Smrg if (n[i] < 0)
117*ba125506Smrg {
118*ba125506Smrg if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
119*ba125506Smrg {
120*ba125506Smrg printf ("Error: rootn(-Inf,%d) <> -0\n", n[i]);
121*ba125506Smrg exit (1);
122*ba125506Smrg }
123*ba125506Smrg }
124*ba125506Smrg else
125*ba125506Smrg {
126*ba125506Smrg if (! MPFR_IS_INF (y) || MPFR_IS_POS (y))
127*ba125506Smrg {
128*ba125506Smrg printf ("Error: rootn(-Inf,%d) <> -Inf\n", n[i]);
129*ba125506Smrg exit (1);
130*ba125506Smrg }
131*ba125506Smrg }
132*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == 0);
133*ba125506Smrg }
134*ba125506Smrg MPFR_ASSERTN (inex == 0);
135*ba125506Smrg }
136*ba125506Smrg
137*ba125506Smrg /* rootn(+/- 0) */
138*ba125506Smrg for (i = 0; i < numberof (n); i++)
139*ba125506Smrg for (sx = -1; sx <= 1; sx += 2)
140*ba125506Smrg {
141*ba125506Smrg mpfr_set_zero (x, sx);
142*ba125506Smrg mpfr_clear_flags ();
143*ba125506Smrg inex = mpfr_rootn_si (y, x, n[i], MPFR_RNDN);
144*ba125506Smrg if (sx > 0 || n[i] % 2 == 0 ? MPFR_IS_NEG (y) : MPFR_IS_POS (y))
145*ba125506Smrg {
146*ba125506Smrg printf ("Error: rootn(%c0,%d) has a wrong sign\n",
147*ba125506Smrg sx > 0 ? '+' : '-', n[i]);
148*ba125506Smrg exit (1);
149*ba125506Smrg }
150*ba125506Smrg if (n[i] < 0)
151*ba125506Smrg {
152*ba125506Smrg if (! MPFR_IS_INF (y))
153*ba125506Smrg {
154*ba125506Smrg printf ("Error: rootn(%c0,%d) is not an infinity\n",
155*ba125506Smrg sx > 0 ? '+' : '-', n[i]);
156*ba125506Smrg exit (1);
157*ba125506Smrg }
158*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
159*ba125506Smrg }
160*ba125506Smrg else if (n[i] > 0)
161*ba125506Smrg {
162*ba125506Smrg if (MPFR_NOTZERO (y))
163*ba125506Smrg {
164*ba125506Smrg printf ("Error: rootn(%c0,%d) is not a zero\n",
165*ba125506Smrg sx > 0 ? '+' : '-', n[i]);
166*ba125506Smrg exit (1);
167*ba125506Smrg }
168*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == 0);
169*ba125506Smrg }
170*ba125506Smrg else
171*ba125506Smrg {
172*ba125506Smrg if (! MPFR_IS_NAN (y))
173*ba125506Smrg {
174*ba125506Smrg printf ("Error: rootn(%c0,0) <> NaN\n", sx > 0 ? '+' : '-');
175*ba125506Smrg exit (1);
176*ba125506Smrg }
177*ba125506Smrg MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
178*ba125506Smrg }
179*ba125506Smrg MPFR_ASSERTN (inex == 0);
180*ba125506Smrg }
181*ba125506Smrg
182*ba125506Smrg /* TODO: complete the tests. */
183*ba125506Smrg
184*ba125506Smrg mpfr_clears (x, y, (mpfr_ptr) 0);
185*ba125506Smrg }
186*ba125506Smrg
187*ba125506Smrg #define TEST_FUNCTION mpfr_rootn_si
188*ba125506Smrg #define INTEGER_TYPE long
189*ba125506Smrg #define INT_RAND_FUNCTION() \
190*ba125506Smrg (randlimb () % 16 == 0 ? randlong () : (long) (randlimb () % 31) - 15)
191*ba125506Smrg #include "tgeneric_ui.c"
192*ba125506Smrg
193*ba125506Smrg int
main(void)194*ba125506Smrg main (void)
195*ba125506Smrg {
196*ba125506Smrg tests_start_mpfr ();
197*ba125506Smrg
198*ba125506Smrg special ();
199*ba125506Smrg
200*ba125506Smrg /* The sign of the random value y (used to generate a potential bad case)
201*ba125506Smrg is negative with a probability 256/512 = 1/2 for odd n, and never
202*ba125506Smrg negative (probability 0/512) for even n (if y is negative, then
203*ba125506Smrg (y^(2k))^(1/(2k)) is different from y, so that this would yield
204*ba125506Smrg an error). */
205*ba125506Smrg bad_cases (root2, pow2, "rootn[2]", 0, -256, 255, 4, 128, 80, 40);
206*ba125506Smrg bad_cases (root3, pow3, "rootn[3]", 256, -256, 255, 4, 128, 200, 40);
207*ba125506Smrg bad_cases (root4, pow4, "rootn[4]", 0, -256, 255, 4, 128, 320, 40);
208*ba125506Smrg bad_cases (root5, pow5, "rootn[5]", 256, -256, 255, 4, 128, 440, 40);
209*ba125506Smrg bad_cases (root17, pow17, "rootn[17]", 256, -256, 255, 4, 128, 800, 40);
210*ba125506Smrg bad_cases (root120, pow120, "rootn[120]", 0, -256, 255, 4, 128, 800, 40);
211*ba125506Smrg
212*ba125506Smrg /* Ditto. */
213*ba125506Smrg bad_cases (rootm2, powm2, "rootn[-2]", 0, -256, 255, 4, 128, 80, 40);
214*ba125506Smrg bad_cases (rootm3, powm3, "rootn[-3]", 256, -256, 255, 4, 128, 200, 40);
215*ba125506Smrg bad_cases (rootm4, powm4, "rootn[-4]", 0, -256, 255, 4, 128, 320, 40);
216*ba125506Smrg bad_cases (rootm5, powm5, "rootn[-5]", 256, -256, 255, 4, 128, 440, 40);
217*ba125506Smrg bad_cases (rootm17, powm17, "rootn[-17]", 256, -256, 255, 4, 128, 800, 40);
218*ba125506Smrg bad_cases (rootm120, powm120, "rootn[-120]", 0, -256, 255, 4, 128, 800, 40);
219*ba125506Smrg
220*ba125506Smrg test_generic_ui (MPFR_PREC_MIN, 200, 30);
221*ba125506Smrg
222*ba125506Smrg tests_end_mpfr ();
223*ba125506Smrg return 0;
224*ba125506Smrg }
225