#include #include #include #include #include #include #include long n_iters; unsigned long gcd(unsigned long a, unsigned long b) { unsigned long temp; while(b) { temp = b; b = a % b; a = temp; } return a; } long time_in_usecs() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000L + tv.tv_usec; } void child(int result_pipe) { long s = 0; mpz_t a, b, c; gmp_randstate_t state; mpz_init(a); mpz_init(b); mpz_init(c); gmp_randinit_default(state); gmp_randseed_ui(state, time_in_usecs() * result_pipe); while(n_iters--) { mpz_urandomb(a, state, 256); mpz_urandomb(b, state, 256); mpz_gcd(c, a, b); s += mpz_cmp_ui(c, 1) == 0; } write(result_pipe, &s, sizeof(s)); } double parent(int n_children) { int *pipes; long results = 0; long temp; int pipefds[2]; int i; int pid; double ratio; pipes = malloc(sizeof(int) * n_children); assert(pipes); for(i = 0; i < n_children; i++) { if(pipe(pipefds)) { perror("couldn't pipe"); exit(1); } pipes[i] = pipefds[0]; pid = fork(); if(pid < 0) { perror("couldn't fork"); exit(1); } else if(pid == 0) { child(pipefds[1]); exit(0); } } for(i = 0; i < n_children; i++) { read(pipes[i], &temp, sizeof(long)); results += temp; } ratio = (double)results/(double)(n_children * n_iters); return sqrt(6.0/ratio); } int main(int argc, char **argv) { assert(argc == 3); n_iters = atol(argv[1])/atol(argv[2]); printf("%.20f\n", parent(atoi(argv[2]))); return 0; }