1 /* Test file for mpfr_const_pi. 2 3 Copyright 1999, 2001-2020 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 #if defined(MPFR_WANT_SHARED_CACHE) && defined(HAVE_PTHREAD) 26 27 # include <pthread.h> 28 29 #define MAX_THREAD 100 30 31 static void * 32 start_routine (void *arg) 33 { 34 mpfr_prec_t p; 35 mpfr_t x; 36 mpfr_prec_t inc = *(int *) arg; 37 mp_limb_t *m; 38 39 for (p = 100; p < 20000; p += 64 + 100 * (inc % 10)) 40 { 41 mpfr_init2 (x, p); 42 m = MPFR_MANT (x); 43 mpfr_const_pi (x, MPFR_RNDD); 44 mpfr_prec_round (x, 53, MPFR_RNDD); 45 if (mpfr_cmp_str1 (x, "3.141592653589793116")) 46 { 47 printf ("mpfr_const_pi failed with threading\n"); 48 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); 49 exit (1); 50 } 51 /* Check that no reallocation has been performed */ 52 MPFR_ASSERTN (m == MPFR_MANT (x)); 53 mpfr_clear (x); 54 } 55 56 pthread_exit (NULL); 57 } 58 59 static void 60 run_pthread_test (void) 61 { 62 int i; 63 int error_code; 64 pthread_t thread_id[MAX_THREAD]; 65 int table[MAX_THREAD]; 66 67 for (i = 0; i < MAX_THREAD; i++) 68 { 69 table[i] = i; 70 error_code = pthread_create(&thread_id[i], 71 NULL, start_routine, &table[i]); 72 MPFR_ASSERTN (error_code == 0); 73 } 74 75 for (i = 0; i < MAX_THREAD; i++) 76 { 77 error_code = pthread_join (thread_id[i], NULL); 78 MPFR_ASSERTN (error_code == 0); 79 } 80 } 81 82 # define RUN_PTHREAD_TEST() \ 83 (MPFR_ASSERTN(mpfr_buildopt_sharedcache_p() == 1), run_pthread_test()) 84 85 #else 86 87 # define RUN_PTHREAD_TEST() ((void) 0) 88 89 #endif 90 91 /* tconst_pi [prec] [rnd] [0 = no print] */ 92 93 static void 94 check_large (void) 95 { 96 mpfr_t x, y, z; 97 98 mpfr_init2 (x, 20000); 99 mpfr_init2 (y, 21000); 100 mpfr_init2 (z, 11791); 101 102 /* The algo failed to round for p=11791. */ 103 (mpfr_const_pi) (z, MPFR_RNDU); 104 mpfr_const_pi (x, MPFR_RNDN); /* First one ! */ 105 mpfr_const_pi (y, MPFR_RNDN); /* Then the other - cache - */ 106 mpfr_prec_round (y, 20000, MPFR_RNDN); 107 if (mpfr_cmp (x, y)) { 108 printf ("const_pi: error for large prec (%d)\n", 1); 109 exit (1); 110 } 111 mpfr_prec_round (y, 11791, MPFR_RNDU); 112 if (mpfr_cmp (z, y)) { 113 printf ("const_pi: error for large prec (%d)\n", 2); 114 exit (1); 115 } 116 117 /* a worst-case to exercise recomputation */ 118 if (MPFR_PREC_MAX > 33440) { 119 mpfr_set_prec (x, 33440); 120 mpfr_const_pi (x, MPFR_RNDZ); 121 } 122 123 mpfr_clears (x, y, z, (mpfr_ptr) 0); 124 } 125 126 /* Wrapper for tgeneric */ 127 static int 128 my_const_pi (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) 129 { 130 return mpfr_const_pi (x, r); 131 } 132 133 #define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) 134 #define TEST_FUNCTION my_const_pi 135 #include "tgeneric.c" 136 137 static void 138 bug20091030 (void) 139 { 140 mpfr_t x, x_ref; 141 int inex, inex_ref; 142 mpfr_prec_t p; 143 int r; 144 145 mpfr_free_cache (); 146 mpfr_init2 (x, MPFR_PREC_MIN); 147 for (p = MPFR_PREC_MIN; p <= 100; p++) 148 { 149 mpfr_set_prec (x, p); 150 inex = mpfr_const_pi (x, MPFR_RNDU); 151 if (inex < 0) 152 { 153 printf ("Error, inex < 0 for RNDU (prec=%lu)\n", 154 (unsigned long) p); 155 exit (1); 156 } 157 inex = mpfr_const_pi (x, MPFR_RNDD); 158 if (inex > 0) 159 { 160 printf ("Error, inex > 0 for RNDD (prec=%lu)\n", 161 (unsigned long) p); 162 exit (1); 163 } 164 } 165 mpfr_free_cache (); 166 mpfr_init2 (x_ref, MPFR_PREC_MIN); 167 for (p = MPFR_PREC_MIN; p <= 100; p++) 168 { 169 mpfr_set_prec (x, p + 10); 170 mpfr_const_pi (x, MPFR_RNDN); 171 mpfr_set_prec (x, p); 172 mpfr_set_prec (x_ref, p); 173 for (r = 0; r < MPFR_RND_MAX; r++) 174 { 175 if (r == MPFR_RNDF) 176 continue; /* the test below makes no sense */ 177 inex = mpfr_const_pi (x, (mpfr_rnd_t) r); 178 inex_ref = mpfr_const_pi_internal (x_ref, (mpfr_rnd_t) r); 179 if (inex != inex_ref || mpfr_cmp (x, x_ref) != 0) 180 { 181 printf ("mpfr_const_pi and mpfr_const_pi_internal disagree for rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 182 printf ("mpfr_const_pi gives "); 183 mpfr_dump (x); 184 printf ("mpfr_const_pi_internal gives "); 185 mpfr_dump (x_ref); 186 printf ("inex=%d inex_ref=%d\n", inex, inex_ref); 187 exit (1); 188 } 189 } 190 } 191 mpfr_clear (x); 192 mpfr_clear (x_ref); 193 } 194 195 int 196 main (int argc, char *argv[]) 197 { 198 mpfr_t x; 199 mpfr_prec_t p; 200 mpfr_rnd_t rnd; 201 202 tests_start_mpfr (); 203 204 p = 53; 205 if (argc > 1) 206 { 207 long a = atol (argv[1]); 208 if (MPFR_PREC_COND (a)) 209 p = a; 210 } 211 212 rnd = (argc > 2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ; 213 214 mpfr_init2 (x, p); 215 mpfr_const_pi (x, rnd); 216 if (argc >= 2) 217 { 218 if (argc < 4 || atoi (argv[3]) != 0) 219 { 220 printf ("Pi="); 221 mpfr_out_str (stdout, 10, 0, x, rnd); 222 puts (""); 223 } 224 } 225 else if (mpfr_cmp_str1 (x, "3.141592653589793116") ) 226 { 227 printf ("mpfr_const_pi failed for prec=53\n"); 228 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); 229 exit (1); 230 } 231 232 mpfr_set_prec (x, 32); 233 mpfr_const_pi (x, MPFR_RNDN); 234 if (mpfr_cmp_str1 (x, "3.141592653468251") ) 235 { 236 printf ("mpfr_const_pi failed for prec=32\n"); 237 exit (1); 238 } 239 240 mpfr_clear (x); 241 242 bug20091030 (); 243 244 check_large (); 245 246 test_generic (MPFR_PREC_MIN, 200, 1); 247 248 RUN_PTHREAD_TEST(); 249 250 /* the following is just to test mpfr_free_cache2 with MPFR_FREE_LOCAL_CACHE, 251 it should not hurt, since the call to mpfr_free_cache in tests_end_mpfr 252 will do nothing */ 253 mpfr_free_cache2 (MPFR_FREE_LOCAL_CACHE); 254 255 tests_end_mpfr (); 256 257 /* another test of mpfr_free_cache2 with MPFR_FREE_LOCAL_CACHE, to check 258 that we can call it when the caches are already freed */ 259 mpfr_free_cache2 (MPFR_FREE_LOCAL_CACHE); 260 261 return 0; 262 } 263