From: uzun@crash.cts.com (Roger Uzun)
Newsgroups: alt.folklore.computers
Subject: Pgm to calculate pi (56 secs on 486/33 46 secs on Amiga 4000)
Date: 1 Jan 93 19:57:22 GMT
Organization: CTS Network Services (crash, ctsnet), El Cajon, CA

The following pgm will calculate pi to arbitrary # of digits.
It is all integer ops, no floating point.
On a 486/33 it can calc 3000 digits in 56 secs, in an Amiga 4000,
3000 digits in 46 secs.  Using SAS/C on the Amiga, using
Metaware High C, 486 protected mode optimized code and the
Phar Lap DOS-Extender on the 486.  Under Tubo-C on a 486/33 it
takes 4.55 Minutes (real mode 286 code)

-Roger
/******* pgm begins here ********/
/* Amiga 3000 can do 3,000 PI digits in approx 3 mins 8.05 seconds */
/* Amiga with 50 mhz 030 can do 3,000 PI digits in approx 2 mins 11 secs */
/* Amiga 4000 in 46 secs */
/* 33 Mhz 386 under Xenix in 1 Min 35 secs */
/* 33 Mhz 386 under Turbo C 7 Mins 58 secs */
/* 33 Mhz 486 under Turbo C 4 Mins 40 secs */
/* 33Mhz 386  under HI C 1 Minute 30 secs */
/* 33Mhz 486  under HI C 0 Minute 56 secs */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <proto/exec.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <exec/execbase.h>

long *ms=0L;
long *mf=0L;
long	kf,ks;
long    cnt,n,temp,nd;
long    i;
long    col,col1;
long    loc,stor[142];

void __inline shift(long *,long *,long,long);
void __inline yprint(long);
void __inline xprint(long);
void main(int,char **);

void __inline 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;
}

void __inline yprint(m)
long m;
{
 
    if (cnt < n)
    {
        if (++col==11)
        {
            col = 1;
            if (++col1==6)
            {
                col1=0;
 		printf("\n");
                printf("%4ld",m%10);
            }
            else {
                printf("%3ld",m%10);
            }
        }
        else {
            printf("%ld",m);
        }
        cnt++;
    }
}

void __inline 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;
}

int __regargs exitproc(int);

int __regargs exitproc(i)
int i;
{
 if (mf)
  {
    FreeMem((char *)mf,((2L*(n+4L)*sizeof(long))));
    mf = 0L;
  }
 if (ms)
  {
    FreeMem((char *)ms,((2L*(n+4L)*sizeof(long))));
    ms = 0L;
  }
 return(0);
}


void main(argc,argv)
int argc;
char *argv[];
{
int i=0;
#ifdef XXX
struct ExecBase **execbaseptr=(struct ExecBase **)4L;
UWORD cpuid;
struct ExecBase *execbase;

 execbase = *execbaseptr;
 cpuid = execbase->AttnFlags;
 if (!(cpuid & AFF_68020))
  {
   printf("You need a 68020 to use this program\n");
   exit(0);
  }
#endif
    if (!(onexit(exitproc)))
     {
      printf("Cannot set up an exit trap\n");
      exit(0);
     }
    stor[i++] = 0;
    if (argc < 2)
    {   if (!argc)
         exit(0);        
        printf("Format is:\n\tPI <# of places>\n");
        exit(0);
    }
    
    n = atol(argv[1]);
    if (n<1L)
     n = 1L;

    mf = (long *)AllocMem((2L*((n+4L)*sizeof(long))),MEMF_CLEAR);
    if (mf==0)
    {
        fprintf(stderr,"Memory allocation failure [mf]\n");
        exit(0);
    }

    ms = (long *)AllocMem((2L*((n+4L)*sizeof(long))),MEMF_CLEAR);
    if (ms==0)
    {
        fprintf(stderr,"Memory allocation failure [ms]\n");
        exit(0);
    }

    printf(
    "\nThe following is an approximation of PI to %ld digits\n",(long)n);
   
    cnt = 0L; 
    kf = 25L;
    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;
    }

    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\n");
}
Newsgroups: alt.folklore.computers,alt.folklore.urban,alt.religion.kibology