Last active
April 21, 2024 09:10
-
-
Save komasaru/68f209118edbac0700da to your computer and use it in GitHub Desktop.
C++ source code to compute pi with Chudnovsky formula and Binary Splitting Algorithm using GMP libarary.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************** | |
* Computing pi by Binary Splitting Algorithm with GMP libarary. | |
**************************************************************/ | |
#include <cmath> | |
#include <iostream> | |
#include <fstream> | |
#include <gmpxx.h> | |
using namespace std; | |
struct PQT | |
{ | |
mpz_class P, Q, T; | |
}; | |
class Chudnovsky | |
{ | |
// Declaration | |
mpz_class A, B, C, D, E, C3_24; // GMP Integer | |
int DIGITS, PREC, N; // Integer | |
double DIGITS_PER_TERM; // Long | |
clock_t t0, t1, t2; // Time | |
PQT compPQT(int n1, int n2); // Computer PQT (by BSA) | |
public: | |
Chudnovsky(); // Constructor | |
void compPi(); // Compute PI | |
}; | |
/* | |
* Constructor | |
*/ | |
Chudnovsky::Chudnovsky() | |
{ | |
// Constants | |
DIGITS = 100; | |
A = 13591409; | |
B = 545140134; | |
C = 640320; | |
D = 426880; | |
E = 10005; | |
DIGITS_PER_TERM = 14.1816474627254776555; // = log(53360^3) / log(10) | |
C3_24 = C * C * C / 24; | |
N = DIGITS / DIGITS_PER_TERM; | |
PREC = DIGITS * log2(10); | |
} | |
/* | |
* Compute PQT (by Binary Splitting Algorithm) | |
*/ | |
PQT Chudnovsky::compPQT(int n1, int n2) | |
{ | |
int m; | |
PQT res; | |
if (n1 + 1 == n2) { | |
res.P = (2 * n2 - 1); | |
res.P *= (6 * n2 - 1); | |
res.P *= (6 * n2 - 5); | |
res.Q = C3_24 * n2 * n2 * n2; | |
res.T = (A + B * n2) * res.P; | |
if ((n2 & 1) == 1) res.T = - res.T; | |
} else { | |
m = (n1 + n2) / 2; | |
PQT res1 = compPQT(n1, m); | |
PQT res2 = compPQT(m, n2); | |
res.P = res1.P * res2.P; | |
res.Q = res1.Q * res2.Q; | |
res.T = res1.T * res2.Q + res1.P * res2.T; | |
} | |
return res; | |
} | |
/* | |
* Compute PI | |
*/ | |
void Chudnovsky::compPi() | |
{ | |
cout << "**** PI Computation ( " << DIGITS << " digits )" << endl; | |
// Time (start) | |
t0 = clock(); | |
// Compute Pi | |
PQT PQT = compPQT(0, N); | |
mpf_class pi(0, PREC); | |
pi = D * sqrt((mpf_class)E) * PQT.Q; | |
pi /= (A * PQT.Q + PQT.T); | |
// Time (end of computation) | |
t1 = clock(); | |
cout << "TIME (COMPUTE): " | |
<< (double)(t1 - t0) / CLOCKS_PER_SEC | |
<< " seconds." << endl; | |
// Output | |
ofstream ofs ("pi.txt"); | |
ofs.precision(DIGITS + 1); | |
ofs << pi << endl; | |
// Time (end of writing) | |
t2 = clock(); | |
cout << "TIME (WRITE) : " | |
<< (double)(t2 - t1) / CLOCKS_PER_SEC | |
<< " seconds." << endl; | |
} | |
int main() | |
{ | |
try | |
{ | |
// Instantiation | |
Chudnovsky objMain; | |
// Compute PI | |
objMain.compPi(); | |
} | |
catch (...) { | |
cout << "ERROR!" << endl; | |
return -1; | |
} | |
return 0; | |
} |
CodeBlocks couldn't run your code, can you please tell me how to install the gmpxx.h library? it won't be installed on my machine
Please refer my blog page.
=> https://www.mk-mode.com/blog/2015/04/21/gmp-installation-by-source-build-on-linux-mint
Very efficient
doesn't compile:
quela@hyperpc:~$ g++ chudnovsky.cpp -o pi -lgmp
/usr/bin/ld: /tmp/ccMmgJZZ.o: in function `std::ostream& operator<< <__mpf_struct [1], __mpf_struct [1]>(std::ostream&, __gmp_expr<__mpf_struct [1], __mpf_struct [1]> const&)':
chudnovsky.cpp:(.text._ZlsIA1_12__mpf_structS1_ERSoS2_RK10__gmp_exprIT_T0_E[_ZlsIA1_12__mpf_structS1_ERSoS2_RK10__gmp_exprIT_T0_E]+0x36): undefined reference to `operator<<(std::ostream&, __mpf_struct const*)'
collect2: error: ld returned 1 exit status
Try to compile with -lgmp and -lgmpxx flags:
g++ -lgmp -lgmpxx chudnovsky.cpp
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome!