我有一个任务,我需要以计算有效的方式近似Pi。这是我的策略:我使用单位圆,等角三角形的角平分线,以及罪的定义。我画了一张图:
例如,如果我想使用六边形(6点/ 6边),我只需要计算a
:( 0.5*sin(2*pi/2*x
)并将其乘以(2*x
) 。最后,从Pi = Circumference/Diameter
开始,然后我的近似值Pi =多边形周长(从Diameter = 1
开始)。
本质:
from math import sin, pi
def computePi(x): #x: number of points desired
p = x*sin(pi/x)
print(p)
computePi(10000)
3.141592601912665
它有效,而且我觉得它有效率,不是吗?谢谢你的时间!
编辑:为了避免循环,我使用阿基米德算法仅使用毕达哥拉斯理论来重新编写:
代码:
from math import sqrt
def approxPi(x): #x: number of times you want to recursively apply Archmidedes' algorithm
s = 1 #Unit circle
a = None; b = None;
for i in range(x):
a = sqrt(1 - (s/2)**2)
b = 1 - a
print('The approximate value of Pi using a {:5g}-sided polygon is {:1.8f}'.format(6*2**(i),(s*6*2**(i))/2))
s = sqrt(b**2 + (s/2)**2)
答案 0 :(得分:5)
更好的是
print(4 * math.atan(1))
这在计算中没有以任何明显的方式使用pi(尽管@ Jean-FrançoisFabre注释,pi可能在函数定义中使用),除了trig函数之外,它只有一个简单的乘法。当然,还有
print(2 * math.acos(0))
和
print(2 * math.asin(1))
答案 1 :(得分:2)
尽管不是非常有效的解决方案,但使用Euler的Basel Problem解决方案是有趣的:
from math import sqrt
def psum(n):
return sum(1/k**2 for k in range(1,n+1))
def approxPi(n):
s = psum(n)
return sqrt(6*s)
例如,
>>> approxPi(100000)
3.141583104326456
正如我所说,效率不高。另一方面,显然没有微妙的循环性。众所周知,许多其他系列会聚到pi
或收敛到可以轻松计算pi
的值,而其他许多系列会更快收敛。
编辑:@Simon关于使用Gauss-Legendre algorithm和模块decimal的建议会导致以下代码(返回结果)作为一个字符串):
import decimal
from decimal import Decimal as d
def approxPi(n):
eps = 1/d(10**n)
decimal.getcontext().prec = 3*n #probably overkill, but need room for products
a = d(1)
b = 1/d(2).sqrt()
t = 1/d(4)
p = d(1)
dif = a-b
if dif < 0: dif = -dif
i = 1
while dif >= eps:
a1 = (a+b)/2
b1 = a*b
b1 = b1.sqrt()
t1 = t - p*(a - a1)**2
p1 = 2*p
a,b,t,p = a1,b1,t1,p1
dif = a1-b1
if dif < 0: dif = -dif
pi = (a + b)**2/(4*t)
return str(pi)[:n+2]
例如,
>>> approxPi(1000)
'3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989'
同意this。
以上不到一秒钟。 10,000秒需要几秒钟。看看用Python获取1,000,000个数字需要多长时间会很有趣。
答案 2 :(得分:1)
以下是您的问题的代码:
from math import radians, sin
def computePi(n):
p = n * (sin(radians((360/(2*n)))))
print(p)
computePi(1000)
此代码背后的理论解释如下:https://math.stackexchange.com/questions/588141/how-is-the-value-of-pi-pi-actually-calculated