This is longpi.c in view mode; [Download] [Up]
/************************************************************************/
/* */
/* LONGPI: calculates the number PI (3.14...) to <n> digits */
/* */
/* */
/* Should compile without any problems on any good ANSI C compiler */
/* */
/* Last changes: 2.12.1991 @pf68030 */
/* */
/************************************************************************/
/*
Execution times for LONGPI 1000 on several computers:
-----------------------------------------------------
Note: calculating 1000 digits of PI requires 8 KBytes of memory. If the
processor cache has at least 8 K things will considerably speed up because
of a cache hit ratio approaching 100% !
Computer type OS CPU, Speed Time used
------------------------------------------------------------------
Atari ST 1040, TOS 1.x 8 MHz 68000 215 s
IBM PS/2, MSDOS 10 MHz 286 207 s
VAX 11/750, VMS 4.7 ? 100 s
AT 386 MSDOS 25 MHz 386DX, 32K Cache 62 s
Atari TT030 TOS 3.0x 32 MHz 68030 37 s (68000 code)
AT 486 EISA MSDOS 5 33 MHz 486DX 32 s
MAC IIsi MacOS 6.0.x 20 MHz 68030 26 s (68020 code)
MAC IIci MacOS 6.0.x 25 MHz 68030 19.8 s (68020 code)
AT 486 EISA MSDOS 33 MHz 486DX 17 s ('386 code)
Atari TT030 TOS 3.0x 32 MHz 68030 13.5 s (68020 code)
HP 9000 UNIX 50 MHz 68030 12.6 s
(+0.1 s systime)
HP 9000 UNIX 25 MHz 68040 9.8 s
(+0.1 s systime)
NeXTstation UNIX 25 MHz 68040 7.3 s
(+0.1 s systime) (added by Xilef)
AT 486 SCO-UNIX 33 MHz 486DX, 64K Cache 6.4 s
SUN Sparcstation2 SunOS Sparc RISC processor 5.1 s
Compilers:
----------
Pure C (Turbo C successor): Atari ST/TT
Quick C IBM PS/2
Turbo C++ AT 486 (32 sec)
Microsoft C AT 486 (17 sec)
VAX 11 C VAX 11/750 (what else ?)
Standard unix compilers ('cc') on *IX systems.
Cache:
------
68000...68010: 0
68020 256 bytes
68030 2*256 bytes (code+data separated)
68040 2*4 Kbytes physical
80286 0
80486 8 Kbytes physical cache (code+data unified)
*/
/************************************************************************/
/* THE PROGRAM... */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef __wrongclock
#define CLK_TCK 60
#endif
#ifdef __TOS__
#define MOTOROLA /* may be defined on _real_ 32 bit architectures */
#endif
clock_t chronometer; /* only available in ANSI C */
long kf,ks,*mf,*ms;
long cnt,n,temp,nd;
long i;
long col,col1;
long loc,stor[100];
FILE *fp;
/* some prototypes ! */
void shift(long *l1, long *l2, long lp, long lmod);
/************************************************************************/
/* launch the 'chronometer' */
void chronostart(void)
{
chronometer=clock();
};
/************************************************************************/
/* get elapsed time */
void chronostop(void)
{
clock_t newtime;
double seconds;
newtime=clock();
seconds=(double)(newtime-chronometer)/(double)CLK_TCK;
printf("time used: %.02lf sec\n", seconds);
fprintf(fp, "\n\ntime used: %.02lf sec\n", seconds);
};
/************************************************************************/
/* output routines: */
void yprint( 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++;
}
}
/************************************************************************/
void xprint( 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 main( int argc, char *argv[] )
{
long i=0; /* temp. variable */
stor[i++] = 0;
if (argc < 2)
{
fprintf(stderr,"Format is:\n\tlongpi <# of places>\n");
exit(-1);
}
n = atol(argv[1]); /* convert to long */
mf = (long *)calloc( (int)(n+8), sizeof(long) );
if (mf==NULL) {
fprintf(stderr,"Memory allocation failure [mf]\n");
exit(-1);
}
ms = (long *)calloc( (int)(n+8), sizeof(long) );
if (ms==NULL) {
fprintf(stderr,"Memory allocation failure [ms]\n");
exit(-1);
}
#ifdef MOTOROLA
/* align to longword boundary ( = more speed in 32 bit systems) */
/* !! casting a pointer to a longword var. only works in _real_ */
/* 32 bit systems such as 680x0, VAX or SUN machines ! */
/* modification 11.11.1992: align to CACHELINE!!! (16 BYTE) */
(long)mf += 16; (long)mf &= 0xFFFFFFF0L;
(long)ms += 16; (long)ms &= 0xFFFFFFF0L;
printf("Memory allocated: &mf[]=$%lX, &ms[]=$%lX; each is %ld bytes.\n",
mf, ms, (n+3)*sizeof(long) );
#else
printf("Memory allocated.");
#endif
fp = fopen("pi.out","w");
fprintf(fp,"\nThe following is an approximation of PI to %ld digits\n",
n);
printf("\nThe following is an approximation of PI to %ld digits\n", n);
chronostart();
cnt = 0;
kf = 25;
ks = 57121L; /* Magische Konstanten */
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");
chronostop();
return(0);
};
/************************************************************************/
/* called very, very often! */
void shift(long *l1, long *l2, long lp, long lmod)
{
register long k,k1;
k=( (k1 = *l2)>0 ? k1/lmod : -(-k1/lmod)-1 );
*l2 -= k*lmod;
*l1 += k*lp;
};
/************************************************************************/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.