Monte Carlo π
Last semester, Rachel had a challenge in one of her classes to compute
as many digits of π as possible using standard Monte Carlo
integration. This was quite an odd challenge considering that a run
with a billion samples is expected to get only 5 digits of accuracy, and
every successive digit requires 100 times as many samples. Rachel ended
up winning the challenge by using a lot of computation time, but I beat
her by cheating in two ways. My program, pi.c
, is below, and it gets
21 digits correct after the decimal point, which is more precise than a
long double
so we have to use bc
to do the final division. It runs
in about 5 minutes on my machine. The explanation of the tricks used is
left as an exercise to the reader.
/*
* usage:
* ./pi | bc
*/
#include <stdio.h>
const unsigned long long m = 2305843009213693951LL;
const unsigned long long a = 1460211800019390769LL;
const unsigned long long b = 1277374150923603017LL;
unsigned long long x = 2198028115820622116LL;
inline long double random_square (void) {
x = (a * x + b) % m;
long double f = (long double) x / m;
return f * f;
}
const long long trials = 26805949036LL;
long long inside = 0;
int main () {
for (long long i = 0; i < trials; i++) {
inside += random_square() + random_square() < 1;
}
printf("scale=22; %lld/%lld\n", 4*inside, trials);
return 0;
}
22 August 2023