forked from TheAlgorithms/Python
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpi_generator.py
More file actions
Latest commit
87 lines (68 loc) · 2.35 KB
/
Copy pathpi_generator.py
File metadata and controls
87 lines (68 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
defcalculate_pi(limit: int) ->str:
"""
https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80
Leibniz Formula for Pi
The Leibniz formula is the special case arctan(1) = pi / 4.
Leibniz's formula converges extremely slowly: it exhibits sublinear convergence.
Convergence (https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80#Convergence)
We cannot try to prove against an interrupted, uncompleted generation.
https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80#Unusual_behaviour
The errors can in fact be predicted, but those calculations also approach infinity
for accuracy.
Our output will be a string so that we can definitely store all digits.
>>> import math
>>> float(calculate_pi(15)) == math.pi
True
Since we cannot predict errors or interrupt any infinite alternating series
generation since they approach infinity, or interrupt any alternating series, we'll
need math.isclose()
>>> math.isclose(float(calculate_pi(50)), math.pi)
True
>>> math.isclose(float(calculate_pi(100)), math.pi)
True
Since math.pi contains only 16 digits, here are some tests with known values:
>>> calculate_pi(50)
'3.14159265358979323846264338327950288419716939937510'
>>> calculate_pi(80)
'3.14159265358979323846264338327950288419716939937510582097494459230781640628620899'
"""
# Variables used for the iteration process
q=1
r=0
t=1
k=1
n=3
m=3
decimal=limit
counter=0
result=""
# We can't compare against anything if we make a generator,
# so we'll stick with plain return logic
whilecounter!=decimal+1:
if4*q+r-t<n*t:
result+=str(n)
ifcounter==0:
result+="."
ifdecimal==counter:
break
counter+=1
nr=10* (r-n*t)
n= ((10* (3*q+r)) //t) -10*n
q*=10
r=nr
else:
nr= (2*q+r) *m
nn= (q* (7*k) +2+ (r*m)) // (t*m)
q*=k
t*=m
m+=2
k+=1
n=nn
r=nr
returnresult
defmain() ->None:
print(f"{calculate_pi(50) =}")
importdoctest
doctest.testmod()
if__name__=="__main__":
main()