1 /* Test file for mpfr_const_pi. 2 3 Copyright 1999, 2001-2018 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 http://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 (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 #else 85 # define RUN_PTHREAD_TEST() \ 86 (MPFR_ASSERTN(mpfr_buildopt_sharedcache_p() == 0)) 87 #endif 88 89 /* tconst_pi [prec] [rnd] [0 = no print] */ 90 91 static void 92 check_large (void) 93 { 94 mpfr_t x, y, z; 95 96 mpfr_init2 (x, 20000); 97 mpfr_init2 (y, 21000); 98 mpfr_init2 (z, 11791); 99 100 /* The algo failed to round for p=11791. */ 101 (mpfr_const_pi) (z, MPFR_RNDU); 102 mpfr_const_pi (x, MPFR_RNDN); /* First one ! */ 103 mpfr_const_pi (y, MPFR_RNDN); /* Then the other - cache - */ 104 mpfr_prec_round (y, 20000, MPFR_RNDN); 105 if (mpfr_cmp (x, y)) { 106 printf ("const_pi: error for large prec (%d)\n", 1); 107 exit (1); 108 } 109 mpfr_prec_round (y, 11791, MPFR_RNDU); 110 if (mpfr_cmp (z, y)) { 111 printf ("const_pi: error for large prec (%d)\n", 2); 112 exit (1); 113 } 114 115 /* a worst-case to exercise recomputation */ 116 if (MPFR_PREC_MAX > 33440) { 117 mpfr_set_prec (x, 33440); 118 mpfr_const_pi (x, MPFR_RNDZ); 119 } 120 121 mpfr_clears (x, y, z, (mpfr_ptr) 0); 122 } 123 124 /* Wrapper for tgeneric */ 125 static int 126 my_const_pi (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) 127 { 128 return mpfr_const_pi (x, r); 129 } 130 131 #define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) 132 #define TEST_FUNCTION my_const_pi 133 #include "tgeneric.c" 134 135 static void 136 bug20091030 (void) 137 { 138 mpfr_t x, x_ref; 139 int inex, inex_ref; 140 mpfr_prec_t p; 141 int r; 142 143 mpfr_free_cache (); 144 mpfr_init2 (x, MPFR_PREC_MIN); 145 for (p = MPFR_PREC_MIN; p <= 100; p++) 146 { 147 mpfr_set_prec (x, p); 148 inex = mpfr_const_pi (x, MPFR_RNDU); 149 if (inex < 0) 150 { 151 printf ("Error, inex < 0 for RNDU (prec=%lu)\n", 152 (unsigned long) p); 153 exit (1); 154 } 155 inex = mpfr_const_pi (x, MPFR_RNDD); 156 if (inex > 0) 157 { 158 printf ("Error, inex > 0 for RNDD (prec=%lu)\n", 159 (unsigned long) p); 160 exit (1); 161 } 162 } 163 mpfr_free_cache (); 164 mpfr_init2 (x_ref, MPFR_PREC_MIN); 165 for (p = MPFR_PREC_MIN; p <= 100; p++) 166 { 167 mpfr_set_prec (x, p + 10); 168 mpfr_const_pi (x, MPFR_RNDN); 169 mpfr_set_prec (x, p); 170 mpfr_set_prec (x_ref, p); 171 for (r = 0; r < MPFR_RND_MAX; r++) 172 { 173 if (r == MPFR_RNDF) 174 continue; /* the test below makes no sense */ 175 inex = mpfr_const_pi (x, (mpfr_rnd_t) r); 176 inex_ref = mpfr_const_pi_internal (x_ref, (mpfr_rnd_t) r); 177 if (inex != inex_ref || mpfr_cmp (x, x_ref) != 0) 178 { 179 printf ("mpfr_const_pi and mpfr_const_pi_internal disagree for rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 180 printf ("mpfr_const_pi gives "); 181 mpfr_dump (x); 182 printf ("mpfr_const_pi_internal gives "); 183 mpfr_dump (x_ref); 184 printf ("inex=%d inex_ref=%d\n", inex, inex_ref); 185 exit (1); 186 } 187 } 188 } 189 mpfr_clear (x); 190 mpfr_clear (x_ref); 191 } 192 193 int 194 main (int argc, char *argv[]) 195 { 196 mpfr_t x; 197 mpfr_prec_t p; 198 mpfr_rnd_t rnd; 199 200 tests_start_mpfr (); 201 202 p = 53; 203 if (argc > 1) 204 { 205 long a = atol (argv[1]); 206 if (MPFR_PREC_COND (a)) 207 p = a; 208 } 209 210 rnd = (argc > 2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ; 211 212 mpfr_init2 (x, p); 213 mpfr_const_pi (x, rnd); 214 if (argc >= 2) 215 { 216 if (argc < 4 || atoi (argv[3]) != 0) 217 { 218 printf ("Pi="); 219 mpfr_out_str (stdout, 10, 0, x, rnd); 220 puts (""); 221 } 222 } 223 else if (mpfr_cmp_str1 (x, "3.141592653589793116") ) 224 { 225 printf ("mpfr_const_pi failed for prec=53\n"); 226 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); 227 exit (1); 228 } 229 230 mpfr_set_prec (x, 32); 231 mpfr_const_pi (x, MPFR_RNDN); 232 if (mpfr_cmp_str1 (x, "3.141592653468251") ) 233 { 234 printf ("mpfr_const_pi failed for prec=32\n"); 235 exit (1); 236 } 237 238 mpfr_clear (x); 239 240 bug20091030 (); 241 242 check_large (); 243 244 test_generic (MPFR_PREC_MIN, 200, 1); 245 246 RUN_PTHREAD_TEST(); 247 248 tests_end_mpfr (); 249 250 return 0; 251 } 252