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 } 225