/* * Speed Fraction * by: Charlton Harrison * Computes the best approximate fractions for a decimal */ #include #include #include /* #include */ #include /* for kbhit() */ #include #include /* Function for kbhit() - the gcc way */ /* Only works for the key though... */ int kbhit() { struct timeval wait; int ret; fd_set readfd; FD_ZERO(&readfd); FD_SET(0, &readfd); wait.tv_sec = 0; /* Wait zero seconds */ wait.tv_usec = 0; ret = select(1, &readfd, NULL, NULL, &wait); return(ret); } int main(int argc, char *argv[]) { int kcount=0; mpz_t lpa, lasta, lastb, a, b, c, e, t, tai, tbi, last10; mpf_t m, p, lastp, x, h, fe, ft, taf, tbf; mpz_init(lpa); mpz_set_ui(lpa, 0); mpz_init(lasta); mpz_set_ui(lasta, 0); mpz_init(lastb); mpz_set_ui(lastb, 0); mpz_init(a); mpz_set_ui(a, 0); mpz_init(b); mpz_set_ui(b, 0); mpz_init(c); mpz_set_ui(c, 1); mpz_init(t); mpz_set_ui(t, 0); mpz_init(e); mpz_init(tai); mpz_init(tbi); mpz_init(last10); mpf_init(m); mpf_set_d(m, 0.5); mpf_init(p); mpf_set_d(p, 0.0); mpf_init(lastp); mpf_set_d(lastp, 0.0); mpf_init(x); mpf_init(h); mpf_init(fe); mpf_init(ft); mpf_init(taf); mpf_init(tbf); /* Initializations */ if (argc != 2) { printf("Usage: spfrcn [decimal]\n"); exit(1); } printf("\nHit return at any time to stop...\n"); /* x = atof(argv[1]); */ mpf_init_set_str(x, argv[1], 10); /* printf("Ok: %.16f\n", x); */ mpf_out_str(stdout, 10, 32, x); printf("\n"); while (1) { /* Main Loop */ /* t++; m+=x; e=m; */ mpz_add_ui(t, t, 1); mpf_add(m, m, x); mpz_set_f(e, m); /* mpz_out_str(stdout, 10, e); printf(" : "); mpf_out_str(stdout, 10, 0, m); printf("\n"); */ /* h=((double)e / (double)t); */ mpf_set_z(fe, e); mpf_set_z(ft, t); mpf_div(h, fe, ft); /* mpz_out_str(stdout, 10, e); printf(" / "); mpz_out_str(stdout, 10, t); printf(" : "); mpf_out_str(stdout, 10, 0, h); printf("\n"); */ mpf_sub(taf, h, x); mpf_sub(tbf, p, x); mpf_abs(taf, taf); mpf_abs(tbf, tbf); /* if (fabs(h-x) < fabs(p-x)) { */ /* mpf_out_str(stdout, 10, 0, taf); printf(" -:- "); mpf_out_str(stdout, 10, 0, tbf); printf("\n"); */ if ((mpf_cmp(taf, tbf)) < 0) { /* p=h; a=e; b=t; */ /*printf("here0\n");*/ mpf_set(p, h); mpz_set(a, e); mpz_set(b, t); } /* if (a != lpa) { */ /* mpz_out_str(stdout, 10, a); printf("=?"); mpz_out_str(stdout, 10, lpa); printf("\n"); */ if ((mpz_cmp(a, lpa)) != 0) { /* if (h==x) { */ if ((mpf_cmp(h, x)) == 0) { /* printf("%ld / %ld : %.16f\n", a, b, p); */ mpz_out_str(stdout, 10, a); printf(" / "); mpz_out_str(stdout, 10, b); printf(" : "); mpf_out_str(stdout, 10, 0, p); printf("\n"); exit(1); } /* last10 = pow(10, ((int)log10(e))); */ mpz_ui_pow_ui(last10, 10, (mpz_sizeinbase(e, 10) - 1)); /* if ((int)(e/last10) != (int)(a/last10)) { */ /* mpz_out_str(stdout, 10, e); printf(" : "); mpz_out_str(stdout, 10, a); printf(" / "); mpz_out_str(stdout, 10, last10); printf("\n"); */ mpz_tdiv_q(tai, e, last10); mpz_tdiv_q(tbi, a, last10); /* printf("here1\n"); mpz_out_str(stdout, 10, tai); printf(" =? "); mpz_out_str(stdout, 10, tbi); printf("\n"); */ if ((mpz_cmp(tai, tbi)) != 0) { /* printf("%ld / %ld : %.16f\n", a, b, p); */ mpz_out_str(stdout, 10, a); printf(" / "); mpz_out_str(stdout, 10, b); printf(" : "); mpf_out_str(stdout, 10, 0, p); printf("\n"); /* lpa=a; */ mpz_set(lpa, a); } } kcount++; if (kcount==1000) { /* every 1000 loops check to see if kbhit */ kcount=0; if (kbhit()) { exit(1); } } } /* End of Main Loop */ }