/* pi.c #2 */ #define pi "3.14159265358979323846264338327950288419716939937510" #include #include #include void sdiv(long num, long den, char *res, int prec); void ssub(char *a, char *b, char *res); int scomp(char *a, char *b); main(int argc, char *argv[]) { long num,den; char acc[100],bacc[100],res[100]; char *acc2; char tr; long cnt = 0; num=1; den=1; if (argc > 1) { num = atol(argv[1]); den = atol(argv[2]); if (den == 0) den = 1; } strcpy(bacc,"9.0000000000000000000000000000000000000000000"); printf("
pi = %-30s\n\n",pi);
	printf("%7s %7s = %-32s (%-23s)\n","Num.","Den.","Result","Accuracy");
	printf("%7s %7s = %-32s (%-23s)\n","-------","-------","----------------------","-----------------------");

	while (1) {
		sdiv(num,den,res,30);
		ssub(pi,res,acc);

/*		if (*kb & 1) cprintf("%7ld/%7ld = %.20s (%.20s)\r",num,den,res,acc);
*/
		if (acc[0] == '-') acc2 = acc+1;
			else acc2 = acc;

		tr = scomp(bacc,acc2);
		if (tr >= 0) {
/*			cprintf("%7ld/%7ld = %.20s (%.20s)",num,den,res,acc);
 */		if (tr == 0) {
				cnt++;
/*				cprintf(" (%d)\n\r",cnt);
 */		} else {
/*				cprintf("\n\r");
 */				if (cnt) printf(" (x %ld)",cnt+1);
				printf("\n%12ld/%12ld = %-30s (%33s)",num,den,res,acc);
				cnt = 0;
				for (cnt=0;acc2[cnt+2] == '0';cnt++);
				printf(" [%2d]",cnt);
				fflush(stdout);
				strcpy(bacc,acc2);
				cnt = 0;
			}
		}

		if (acc[0] == '-') {
			den+=1;
		} else {
			num+=1;
		}
	}
	printf("\n
\n"); } /* ssub - subtracts two strings * MUST BE DECIMAL ALIGNED! */ int ssub_borrow(char *a, char p) { if (p == -1) return 0; if (a[p] == '.') { return ssub_borrow(a,p-1); } else if (a[p] == '0') { a[p] = '9'; return ssub_borrow(a,p-1); } else { a[p]--; } return 1; } void ssub(char *a, char *b, char *res) { int p; int rp; int tr; p = 0; rp = 0; while (a[p] && b[p]) { if (a[p] == '.') { res[rp++] = '.'; p++; } tr = a[p] - b[p]; if (tr < 0) { if (ssub_borrow(res,p-1)) { tr += 10; } else { res[0] = '-'; ssub(b,a,res+1); return; } } res[rp++] = '0' + tr; p++; } res[rp] = 0; } /* scomp - compares two strings * MUST BE DECIMAL ALIGNED! * return 0 - a < b * return 1 - a > b */ int scomp(char *a, char *b) { int p; p = 0; while (a[p] && b[p]) { if (a[p] < b[p]) return -1; if (a[p] > b[p]) return 1; p++; } return 0; } /* sdiv - divide two ints - result put in a string * */ void sdiv(long num, long den, char *res, int prec) { int p,pp; unsigned long car,ocar,t; int rp; char nums[20]; char unums; sprintf(nums,"%ld",num); rp = 0; unums = 1; car = 0; p = 0; pp = 0; res[0] = 0; while (pp < prec) { car *= 10; if (unums) { if (nums[p]) { car += nums[p] - '0'; } else { unums = 0; res[rp++] = '.'; pp++; } } else pp++; ocar = car; t = car / den; if (t || res[0]) res[rp++] = '0' + t; t *= den; car = ocar - t; p++; if (car == 0 && unums == 0) break; } while (pp < prec) { res[rp++] = '0'; pp++; } res[rp] = 0; } /* 001 234 | 2354908123 02 0 23 = 0 235 234 = 14 */ /* 3.1297321 3.1278412 0.0018909 3.1297321 3.1278412 -0.001 */