#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/resource.h>

#include <gmp.h>
#define BASE 10

//void arctan(mpq_t x,int,mpq_t);

void arctan_euler (int, int, mpq_t);
void pi_machin (int, mpq_t);
void ratodecimal (mpq_t q, int n);

int
main (int argc, char *argv[])
{
  setpriority(0,0,19);
  mpq_t ans;
  mpq_init (ans);
  pi_machin (1000000, ans);

}				/*
				   void arctan(mpq_t x,int one, mpq_t ans){
				   mpq_div(power,one,x);
				   int delta;
				   mpq_init(ans,power);
				   mpq_t x_squared(ans,x,x);
				   int divisor =1;
				   while(1){
				   power -=power;
				   divisor+=2;
				   delta=power;
				   if(delta==0)break;
				   else mpq_add(ans,ans,delta);
				   }
				   } */
void
arctan_euler (int xform, int one, mpq_t total)
{
  mpq_t zer,funone,x, x_squared,justone,justtwo, x_squared_plus_1, term, two_n, divisor,twon_p1,nifif;

  int i=0;
  
  mpq_init(nifif);
  mpq_init(zer);
  mpq_init(twon_p1);
  mpq_init(funone);
  mpq_init (x);
  mpq_init(x_squared);
  mpq_init(justone);
  mpq_init(justtwo);
  mpq_init(x_squared_plus_1);
  mpq_init(term); 
  mpq_init(two_n); 
  mpq_init(divisor);

  mpq_set_ui(nifif,999999999999999,1);
  mpq_set_ui(zer,1,999999999999999);
  mpq_set_ui (x, xform, 1);
  mpq_set_ui (justone, 1, 1);
  mpq_set_ui (divisor, 1, 1);
  mpq_set_ui (justtwo, 2, 1);
  mpq_set_ui (funone,one,1);
  
  for(i=0;i<=40000;i++){
  mpq_div(zer,zer,nifif);  
  }
  mpq_mul (x_squared, x, x);
  mpq_add (x_squared_plus_1, x_squared, justone);
  mpq_mul (term, x, justone);
 
  mpq_div (term, term, x_squared_plus_1);
  mpq_set (total, term);
  mpq_set_ui (two_n, 2, 1);
  while (1)
    {

      mpq_add (twon_p1, two_n, justone);
      mpq_mul (divisor, twon_p1, x_squared_plus_1);
      mpq_mul (term, term, two_n);
      mpq_div (term, term, divisor);
/*
      if (mpz_cmp_ui(mpq_numref(term),0)==0)
	break;
  */
      if(mpq_cmp(term,zer)<0)break;    
	
      mpq_add (total, total, term);
      mpq_add (two_n, two_n, justtwo);
      
    }
  
}

void
pi_machin (int one, mpq_t ans)
{

  mpq_t ans1, ans2, fouur;

  mpq_init (ans1);
  mpq_init (ans2); 
  mpq_init (fouur);
  mpq_set_ui(ans1,0,1);
  mpq_set_ui(ans2,0,1);
  mpq_set_ui (fouur, 4, 1);

  arctan_euler (5, one, ans1);
  arctan_euler (239, one, ans2);
 
  mpq_mul(ans1,fouur,ans1);
  mpq_sub (ans, ans1, ans2);
  mpq_mul (ans, ans, fouur);
  ratodecimal (ans, 1000000);
  printf("\n");
}

void
ratodecimal (mpq_t q, int n)
{
  int i;
  mpz_t num, den, res, rem;

  mpz_init (num);
  mpz_init (den);
  mpz_init (res);
  mpz_init (rem);

  mpq_get_num (num, q);
  mpq_get_den (den, q);
  mpz_tdiv_qr (res, rem, num, den);
  mpz_out_str (stdout, BASE, res);
  putchar ('.');

  for (i = 0; i < n; i++)
    {
      mpz_mul_ui (num, rem, BASE);
      mpz_tdiv_qr (res, rem, num, den);
      mpz_out_str (stdout, BASE, res);
    }
}