"Fossies" - the Fresh Open Source Software Archive 
Member "mapm_4.9.5a/PI_DEMO/pi_4.cpp" (21 Feb 2010, 4158 Bytes) of package /linux/misc/old/mapm-4.9.5a.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "pi_4.cpp" see the
Fossies "Dox" file reference documentation.
1
2 /****************************************************************************/
3
4 /*
5 * PI_4.CPP
6 *
7 * DEMO 'C++' PROGRAM TO COMPUTE PI USING
8 * J.BORWEIN-P.BORWEIN'S ALGORITHM (1995)
9 *
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "m_apm.h"
16
17 #define FALSE 0
18 #define TRUE 1
19
20
21 extern MAPM compute_PI_2(int);
22
23
24 int main(int argc, char *argv[])
25 {
26 int ii, dplaces;
27 char *buffer;
28 MAPM pi_mapm; /* declare the MAPM variable ... */
29
30 if (argc < 2)
31 {
32 fprintf(stdout,"\nUsage: pi_4 digits\t\t\t\t[Version 1.1]\n");
33 fprintf(stdout,
34 " Compute PI to \'digits\' decimal places of accuracy\n");
35
36 exit(4);
37 }
38
39 dplaces = atoi(argv[1]);
40
41 if (dplaces < 2)
42 {
43 fprintf(stdout,"\nUsage: pi-4 digits \n");
44 exit(6);
45 }
46
47 fprintf(stderr, "\nstart Borwein-Borwein PI calculation \n");
48
49 pi_mapm = compute_PI_2(dplaces);
50
51 fprintf(stderr, "Borwein-Borwein PI calculation complete \n\n");
52
53 /*
54 * find out how many digits so we can
55 * convert the entire value into a string.
56 * (plus some pad for decimal point, exponent, etc)
57 */
58
59 ii = pi_mapm.significant_digits() + 12;
60
61 if ((buffer = (char *)malloc(ii)) == NULL)
62 {
63 fprintf(stdout,"PI demo: Out of memory \n");
64 exit(8);
65 }
66
67
68 /* now convert the MAPM number into a string */
69
70 pi_mapm.toString(buffer, dplaces);
71 printf("Borwein PI = [%s] \n",buffer);
72
73 free(buffer);
74
75 exit(0);
76 }
77
78 /****************************************************************************/
79
80 /*
81 * Calculate PI using the J. Borwein - P. Borwein's Algorithm (1995)
82 *
83 *
84 * Init : A0 = 6 - 4 * sqrt(2)
85 * B0 = sqrt(2) - 1
86 *
87 * Iterate:
88 *
89 * 4
90 * 1 - quart( 1 - B )
91 * k
92 * B = --------------------
93 * k+1 4
94 * 1 + quart( 1 - B )
95 * k
96 *
97 *
98 * 4 2k+3 2
99 * A = A ( 1 + B ) - 2 B ( 1 + B + B )
100 * k+1 k k+1 k+1 k+1 k+1
101 *
102 *
103 *
104 *
105 * where quart(x) = sqrt(sqrt(x)) = 4th root of x
106 *
107 * 1
108 * A ---> -----
109 * k+1 PI
110 *
111 */
112
113 MAPM compute_PI_2(int places)
114 {
115 MAPM t1, t2, c2, a0, a1, b0, b1;
116 int kk, nn, dplaces, dflag;
117
118
119 dplaces = places + 16; // compute a few extra digits
120 // in the intermediate math
121
122 m_apm_cpp_precision(dplaces); // tell C++ our precision requirements
123
124 dflag = FALSE;
125 kk = 0;
126
127 t1 = sqrt("2.0"); // make sure we use the MAPM sqrt
128 a0 = 6 - 4 * t1;
129 b0 = t1 - 1;
130 c2 = 2;
131
132 while (TRUE)
133 {
134 t1 = b0.ipow(4); // t1 = b0 ^ 4
135 t1 = sqrt(sqrt(1 - t1)); // t1 = root_4(1 - t1)
136 t1 = t1.round(dplaces);
137
138 b1 = (1 - t1) / (1 + t1);
139 b1 = b1.round(dplaces);
140
141 t2 = 1 + b1;
142 t2 = t2.ipow(4); // t2 = (1 + b1) ^ 4
143 t2 = t2.round(dplaces);
144
145 t1 = c2.ipow(2 * kk + 3); // t1 = 2 ^ (2*kk+3)
146
147 a1 = a0 * t2 - t1 * b1 * (1 + b1 + b1 * b1);
148 a1 = a1.round(dplaces);
149
150 if (dflag)
151 break;
152
153 // compute the difference from this
154 // iteration to the last one.
155
156 t1 = a1 - a0;
157
158 if (kk >= 3)
159 {
160 // if diff == 0, we're done.
161
162 if (t1 == 0)
163 break;
164 }
165
166 /*
167 * if the exponent of the error term (small error like 2.47...E-65)
168 * is small enough, break out after the *next* a1 is calculated.
169 *
170 * get the exponent of the error term, which will be negative.
171 */
172
173 nn = -(t1.exponent());
174
175 // normally, this wouldn't be here. it's nice in the demo though.
176
177 fprintf(stderr, "PI now known to %d digits of accuracy ... \n",(4 * nn));
178
179 if ((15 * nn) >= dplaces)
180 dflag = TRUE;
181
182 // set up for the next iteration
183
184 b0 = b1;
185 a0 = a1;
186 kk++;
187 }
188
189 // round to the accuracy asked for after taking the reciprocal
190
191 t1 = 1 / a1;
192 return(t1.round(places));
193 }
194
195 /****************************************************************************/
196