/* * PI - program to print PI to N places * 1st argument is the number of places desired. Space is allocated * by dynamic allocation. * * Programmed by Bill Davidsen after the method of G. M. Roe, * based on a version for "E" supplied with the "B" compiler, 1970 * * Modified by Alexander Morris, September 9, 1987 to be fully compatible * with Borland's Turbo C * * 3 May, 1990: Cleaned up by Kim Moser: prototyped functions and made * truly compatible with Turbo C 2.0. Changed code where necessary to * prevent compiler from issuing warnings. */ #include #include #include /* kbhit() */ #include #define max_stor 21 static long zero = 0; static long cnt, n, i, nd; static long col, col1; static long loc, stor[max_stor]; static long readnthlong(FILE *fp, long p); static long readnthlong(FILE *fp, long p) /* Assumes 'fp' is a file of long. Returns p'th long in file. */ { long r; fseek(fp, p*sizeof(long), SEEK_SET); fread((void*) &r, sizeof(r), 1, fp); return r; } static void read2longs(FILE *fp, long p, long *dest); static void read2longs(FILE *fp, long p, long *dest) { fseek(fp, p*sizeof(long), SEEK_SET); fread((void*) dest, sizeof(long), 2, fp); } static void writenthlong(FILE *fp, long p, long l); static void writenthlong(FILE *fp, long p, long l) /* Assumes 'fp' is a file of longs. Writes 'l' as p'th long in file. */ { fseek(fp, p*sizeof(long), SEEK_SET); fwrite((void*) &l, sizeof(l), 1, fp); } static void write2longs(FILE *fp, long p, long *src); static void write2longs(FILE *fp, long p, long *src) { fseek(fp, p*sizeof(long), SEEK_SET); fwrite((void*) src, sizeof(long), 2, fp); } static void shift(long *l1, long *l2, long lp, long lmod); static void shift(long *l1, long *l2, long lp, long lmod) { long k; k = ((*l2) > 0 ? (*l2) / lmod : -(-(*l2) / lmod) - 1); *l2 -= k * lmod; *l1 += k * lp; } static void yprint (long m); static void yprint (long m) { if (cnt < n) { if (++col == 6) { col = 1; if (++col1 == 10) { col1 = 0; printf ("\n%4ld", m % 10); if (!isatty(fileno(stdout))) fprintf(stderr, "\n%4ld", m % 10); } else { printf ("%2ld", m % 10); if (!isatty(fileno(stdout))) fprintf(stderr, "%2ld", m % 10); } } else { printf ("%ld", m); if (!isatty(fileno(stdout))) fprintf(stderr, "%ld", m); } cnt++; } } static void xprint(long m); static void xprint(long m) { long i, wk, wk1; if (m < 8) { for (i = 1; i <= loc;) yprint (stor[i++]); 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; } #define kf 25 #define ks 57121L static void usage(void); static void usage(void) { fprintf(stderr, "USAGE: longpi []\n"); exit(-1); } static void tfo_err(char *s); static void tfo_err(char *s) { fprintf(stderr, "Error opening temp file '%s'.\n", s); exit(-1); } static void tfc_err(char *s); static void tfc_err(char *s) { fprintf(stderr, "Error closing temp file '%s'.\n", s); /* Do not exit! */ } static void readdat(FILE *fp); static void readdat(FILE *fp) { fscanf(fp, "%ld\n%ld\n%ld\n%ld\n%ld\n%ld\n%ld\n", &cnt, &n, &i, &nd, &col, &col1, &loc); for (i=0; i 2) usage(); if (argc > 1) { /* Start from beginning */ if ((n = atol (argv[1])) == 0) usage(); fprintf(stderr, "Preparing to compute pi to %ld places...\n", n); if ((fp_dat = fopen(fname_dat, "w")) == NULL) tfo_err(fname_dat); if ((fp_mf = fopen(fname_mf, "wb+")) == NULL) tfo_err(fname_mf); if ((fp_ms = fopen(fname_ms, "wb+")) == NULL) tfo_err(fname_ms); for (i=0; i= 2;) { temp = 2 * i - 1; read2longs(fp_mf, i-1, t); shift(t, t+1, temp - 2, temp * kf); write2longs(fp_mf, i-1, t); read2longs(fp_ms, i-1, t); shift(t, t+1, temp - 2, temp * ks); write2longs(fp_ms, i-1, t); } nd = 0; t[0] = readnthlong(fp_mf, 1L); shift(&nd, t, 1L, 5L); writenthlong(fp_mf, 1L, t[0]); t[0] = readnthlong(fp_ms, 1L); shift(&nd, t, 1L, 239L); writenthlong(fp_ms, 1L, t[0]); xprint (nd); } if (fclose(fp_mf)) tfc_err(fname_mf); if (fclose(fp_ms)) tfc_err(fname_ms); if (fclose(fp_dat)) tfc_err(fname_dat); exit(0); }