#include<stdio.h>
#include<gmp.h>
#include<stdlib.h>
#define NT 4
#define LIMIT 500000
#define DIGITS 500000
void *worker1(void *ptr);
void *worker2(void *ptr);
int start_i1=1,start_i2=1,end_i1,end_i2;
int thid[NT];
pthread_mutex_t mut1,mut2;
mpz_t f1,f2;
mpq_t ratio1,ratio2;
mpq_t total1,total2;
int main(int argc, char *argv[])
{
int i,j;
unsigned long int seti,setn;
setpriority(0,0,20);
pthread_t th[NT];
pthread_mutex_init(&mut1,0);
pthread_mutex_init(&mut2,0);
end_i1 = end_i2 = LIMIT/NT;
for(i=0;i<NT;i++)
thid[i] = i;
for(i=0;i<NT;i++)
{
if(i%2 == 0)
pthread_create(&th[i],0,worker1,&thid[i]);
else
pthread_create(&th[i],0,worker2,&thid[i]);
}
for(i=0;i<NT;i++)
pthread_join(th[i],0);
mpq_t final;
mpq_init(final);
mpz_mul_ui(mpq_numref(total1),mpq_numref(total1),16);
mpz_mul_ui(mpq_numref(total2),mpq_numref(total2),4);
FILE *fd;
fd = fopen("pi.txt","a");
mpq_sub(final,total1,total2);
mpq_canonicalize(final);
mpz_t num,den,quo,rem;
mpz_init(num);
mpz_init(den);
mpz_init(quo);
mpz_init(rem);
mpq_get_num(num,final);
mpq_get_den(den,final);
mpz_tdiv_qr(quo,rem,num,den);
mpz_out_str(fd,10,quo);
fputs(".",fd);
for(j=0;j<=DIGITS;j++)
{
mpz_mul_ui(num,rem,10);
mpz_tdiv_qr(quo,rem,num,den);
mpz_out_str(fd,10,quo);
}
}
void *worker1(void *ptr)
{
int i;
unsigned long int seti,setn;
pthread_mutex_lock(&mut1);
if(start_i1 == 1)
{
mpq_init(ratio1);
mpz_init(f1);
mpq_init(total1);
mpq_set_ui(total1,1,5);
}
for(i=start_i1; i<=end_i1; i++)
{
seti = i%2 == 0 ? 1:-1;
setn = 2*i+1;
mpz_ui_pow_ui(f1,5,setn);
mpz_mul_ui(f1,f1,setn);
mpq_set_si(ratio1,seti,1);
mpq_set_den(ratio1,f1);
mpq_add(total1,total1,ratio1);
}
start_i1 = end_i1 + 1;
end_i1 += end_i1;
pthread_mutex_unlock(&mut1);
pthread_exit(ptr);
}
void *worker2(void *ptr)
{
int i;
unsigned long int seti,setn;
pthread_mutex_lock(&mut2);
if(start_i2 == 1)
{
mpq_init(ratio2);
mpz_init(f2);
mpq_init(total2);
mpq_set_ui(total2,1,239);
}
for(i=start_i2; i<=end_i2; i++)
{
seti = i%2 == 0 ? 1:-1;
setn = 2*i+1;
mpz_ui_pow_ui(f2,239,setn);
mpz_mul_ui(f2,f2,setn);
mpq_set_si(ratio2,seti,1);
mpq_set_den(ratio2,f2);
mpq_add(total2,total2,ratio2);
}
start_i2 = end_i2 + 1;
end_i2 += end_i2;
pthread_mutex_unlock(&mut2);
pthread_exit(ptr);
}