1+ #include " ChudnovskyPiBS.h"
2+
3+
4+ ChudnovskyPiBS::ChudnovskyPiBS (unsigned long _digits)
5+ {
6+ digits = _digits;
7+ if (_digits != (unsigned long )((long double )_digits))
8+ throw _EXCEPTION_; // precision can't be handled by long double.
9+ N = (unsigned long )(digits / DIGITS_PER_TERM + 1 );
10+
11+ mpz_ui_pow_ui (one_squared.get_mpz_t (), 10 , 2 * digits);
12+
13+ // one_squared.get_str();
14+
15+ mpz_class thousandandfive__times__one_squared = 10005 * one_squared;
16+ mpz_sqrt (sqrtC.get_mpz_t (), thousandandfive__times__one_squared.get_mpz_t ());
17+
18+ // sqrtC.get_str();
19+
20+ mpz_ui_pow_ui (intBigC3_OVER_24.get_mpz_t (), C, 3 );
21+ mpz_class twentyfour = 24 ;
22+ mpz_fdiv_q (intBigC3_OVER_24.get_mpz_t (), intBigC3_OVER_24.get_mpz_t (), twentyfour.get_mpz_t ());
23+ // intBigC3_OVER_24.get_str();
24+ }
25+
26+
27+
28+
29+ bsReturn ChudnovskyPiBS::bs (mpz_class a, mpz_class b)
30+ {
31+ bsReturn result;
32+ mpz_class Pab;
33+ mpz_class Qab;
34+ mpz_class Tab;
35+ mpz_class m;
36+ if (b - a == 1 )
37+ {
38+ // Directly compute P(a,a+1), Q(a,a+1) and T(a,a+1)
39+ if (a == 0 )
40+ Pab = Qab = 1 ;
41+ else
42+ {
43+ Pab = (6 * a - 5 ) * (2 * a - 1 ) * (6 * a - 1 );
44+ Qab = a * a * a * intBigC3_OVER_24;
45+ }
46+
47+ Tab = Pab * (13591409 + 545140134 * a); // a(a) * p(a)
48+ // Pab.get_str();
49+ // Tab.get_str();
50+ // a.get_str();
51+ // Qab.get_str();
52+ mpz_class toCheck;
53+ mpz_and (toCheck.get_mpz_t (), a.get_mpz_t (), one);
54+ if (toCheck == 1 ) // note to self: works as expected
55+ Tab = -Tab;
56+ }
57+ else
58+ {
59+ // Recursively compute P(a,b), Q(a,b) and T(a,b)
60+ // m is the midpoint of and b
61+ mpz_class aplusb = a + b;
62+ mpz_div_ui (m.get_mpz_t (), aplusb.get_mpz_t (), 2 );// equivalent pseudocode: m=floor((a+b)/2)
63+ // Recursively calculate P(a, m), Q(a, m) and T(a, m)
64+ bsReturn am = bs (a, m);
65+ // Recursively calculate P(m, b), Q(m, b) and T(m, b)
66+ bsReturn mb = bs (m, b);
67+ // Now combine
68+ Pab = am.P * mb.P ;
69+ Qab = am.Q * mb.Q ;
70+ Tab = (mb.Q * am.T ) + (am.P * mb.T );
71+ }
72+ result.P = Pab;
73+ result.Q = Qab;
74+ result.T = Tab;
75+ // std::string pabStr = result.P.get_str();
76+ // std::string qabStr = result.Q.get_str();
77+ // std::string tabStr = result.T.get_str();
78+ return result;
79+ }
80+
81+
82+
83+ mpz_class ChudnovskyPiBS::calculatePi ()
84+ {
85+ bsReturn BSResult = bs (0 , N); // apparently Q and T gotten are wrong.
86+ // BSResult.Q.get_str();
87+ // BSResult.T.get_str();
88+ // return mpz_fdiv_q((Q * 426880 * sqrtC) / T
89+ mpz_class result = (BSResult.Q * 426880 * sqrtC);
90+ mpz_fdiv_q (result.get_mpz_t (), result.get_mpz_t (), BSResult.T .get_mpz_t ());
91+ return result;
92+ }
0 commit comments