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