#include <stdio.h>

long kf,ks,*mf,*ms;
long    cnt,n,temp,nd;
long    i;
long    col,col1;
long    loc,stor[21];
FILE    *fp;

shift(l1,l2,lp,lmod)
long *l1,*l2,lp,lmod;
{
long k;
     k=((*l2)>0 ? (*l2)/lmod : -(-(*l2)/lmod)-1);
     *l2 -= k*lmod;
     *l1 += k*lp;
}

yprint(m)
long m;
{
 
    if (cnt < n)
    {
        if (++col==11)
        {
            col = 1;
            if (++col1==6)
            {
                col1=0;
                fprintf(fp,"\n");
   printf("\n");
                fprintf(fp,"%4ld",m%10);
                printf("%4ld",m%10);
            }
            else {
                fprintf(fp,"%3ld",m%10);
                printf("%3ld",m%10);
            }
        }
        else {
            fprintf(fp,"%ld",m);
            printf("%ld",m);
        }
        cnt++;
    }
}

xprint(m)
long m;
{
long ii,wk,wk1;

    if (m<8)
    {
        for (ii=1; ii<=loc;)
            yprint(stor[ii++]);
        loc=0;
    }
    else
    if (m>9)
    {
        wk = m/10;
        m %= 10;
        for (wk1=loc; wk1>=1;wk1--)
        {
            wk += stor[wk1];
            stor[wk1] = wk % 10;
            wk /= 10;
        }
    }
    stor[++loc] = m;
}

main(argc,argv)
int argc;
char *argv[];
{
int i=0;

    stor[i++] = 0;
    if (argc < 2)
    {           
        fprintf(stderr,"Format is:\n\tlongpi <# of places>\n");
        exit();
    }
    
    n = atoi(argv[1]);

    mf = (long *)calloc((int)n+3, sizeof(long));
    if (mf==0)
    {
        fprintf(stderr,"Memory allocation failure [mf]\n");
        exit();
    }

    ms = (long *)calloc((int)n+3, sizeof(long));
    if (ms==0)
    {
        fprintf(stderr,"Memory allocation failure [ms]\n");
        exit();
    }

    printf("Memory allocated.\n");

    fp = fopen("ram:pi.out","w");
    fprintf(fp,"\nThe following is an approximation of PI to %ld digits\n",(long)n);
    printf("\nThe following is an approximation of PI to %ld digits\n",(long)n);
   
    cnt = 0;
    kf = 25;
    ks = 57121L;
    mf[1] = 1;
    for (i=2; i<=n; i+=2)
    {
        mf[i] = -16;
        mf[i+1] = 16;
    }

    for (i=1; i<=n; i+=2)
    {
        ms[i] = -4;
        ms[i+1] = 4;
    }

    fprintf(fp,"\n 3.");
    printf("\n 3.");
   
    while (cnt < n)
    {
        for (i=0; ++i<=n-cnt;)
        {
            mf[i] *= 10;
            ms[i] *= 10;
        }
        for (i=n-cnt+1; --i>=2;)
        {
            temp = 2*i-1;
            shift(&mf[i-1],&mf[i],temp-2,temp*kf);
            shift(&ms[i-1],&ms[i],temp-2,temp*ks);
        }
        nd = 0;
        shift(&nd,&mf[1],1L,5L);
        shift(&nd,&ms[1],1L,239L);
        xprint(nd);
    }
    printf("\n\nCalculations Completed!\n");
}
   
