xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tconst_pi.c (revision eceb233b9bd0dfebb902ed73b531ae6964fa3f9b)
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