I wrote this method:
def approx_pi(n, p):
"""
Approximates Pi by putting dots in a square and counting
the dots in the max possible circle in that square.
:param n: Number of dots
:param p: Precision used for urandom
:return: Approximation of Pi
"""
in_circle = 0
k = 100
max_int = (2**(8*p)-1)
for i in range(n):
# get two random Numbers between 0 and 1
x = int.from_bytes(os.urandom(p), byteorder='big')/max_int
y = int.from_bytes(os.urandom(p), byteorder='big')/max_int
if x ** 2 + y ** 2 <= 1:
in_circle += 1
# Just for debugging
if (i+1) % k == 0:
k = int(k*1.01)
print(i, '\t',4*in_circle/i)
sys.stdout.flush()
return 4*in_circle/n
In most of my Testruns, it is getting stable at 3.141 and then diverges around that value. Is this a weakness of urandom? But if so, why isn't pi shifting in one direction? Or is there something wrong with my code.
First of all. Your code is very confusing. It is better if you call the variables by a name that give you an idea about what they mean.
I have simplified the code to the necessary lines. Hence, I use random library for generating the points position.
The problem with this method is that it converges very slowly. With 10**8 points i got 3.14167604.
EDITING You were rigth about the function random.random(). So in the next code I have used random.random_integers which is a uniform distribution between [low, high] values.
The code is parallelized and i tried for 10**10 points getting:
PI = 3.14157765 Tiempo de calculo = 3790 seconds