Python 用itertools和Leibniz级数逼近Pi值
编写一个程序,通过对该系列的项求和来近似ππ的值:Python 用itertools和Leibniz级数逼近Pi值,python,Python,编写一个程序,通过对该系列的项求和来近似ππ的值: (4/1) - (4/3) + (4/5) - (4/7) + (4/9) - (4/11) + …… 这个代码有什么问题 def main(): n=eval(input("Enter N: ")) x,y=0,0 for i,j in itertools.product ((1,1+4*round((n//2)),4),(-3,-3-4*int((n/2)),-4)): x=x+
(4/1) - (4/3) + (4/5) - (4/7) + (4/9) - (4/11) + ……
这个代码有什么问题
def main():
n=eval(input("Enter N: "))
x,y=0,0
for i,j in itertools.product ((1,1+4*round((n//2)),4),(-3,-3-4*int((n/2)),-4)):
x=x+(4/i)
y=y+(4/j)
print(x+y)
这个代码有什么问题
很多:
- 可读性:它没有解释它的目的是什么
- 可用性:用户必须在不知道它有什么好处的情况下输入N
- 可维护性:for循环有半打常量,称为“幻数”,没有任何解释
- 可读性:莱布尼茨系列非常简单。为什么代码如此复杂
- 正确性:您实现了
,但从未调用它main()
- 安全性:
是危险的eval()
- 添加注释、代码的作用、公式的描述位置等
- 为用户输入改进问题
- 去掉复杂的代码,实现一个简单的求和算法
- 尽可能使用公式以避免混淆。
已经是一个延伸4*
- 使用
而不是int()
从用户输入中获取数字eval()
# Approximation of Pi using the Leibniz series
# See https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80
# k is used as described on Wikipedia
# n is the number of approximation steps. n → ∞ to get close approximations
n = int(input("Enter the number of approximation steps:"))
pi = 0
for k in range(0, n):
pi += 4* (-1)**k / (2*k+1)
print(pi)
对于10.000.000步,它给出了3.14159255,因此您确实需要大量的N
如果您想提高输出的精度,使用@Patrick Artner建议的
分数是个好主意。但这确实减慢了计算速度。这里有一个比较:
N | FP | Fractions | Diff
-------+----------------------+----------------------+---------
10000 | 3.1414926535900 345 | 3.1414926535900 434 | + 89E-16
20000 | 3.141542653589824 8 | 3.141542653589824 3 | - 5E-16
30000 | 3.14155932025646 20 | 3.14155932025646 93 | + 73E-16
40000 | 3.14156765358979 85 | 3.14156765358979 70 | - 15E-16
50000 | 3.1415726535897 814 | 3.1415726535897 950 | +136E-16
60000 | 3.1415759869231 020 | 3.1415759869231 277 | +257E-16
70000 | 3.141578367875 4820 | 3.141578367875 5083 | +263E-16
80000 | 3.1415801535897 496 | 3.1415801535897 936 | +440E-16
90000 | 3.1415815424786 238 | 3.1415815424786 824 | +586E-16
100000 | 3.1415826535897 198 | 3.1415826535897 935 | +740E-16
110000 | 3.141583562680 6436 | 3.141583562680 7027 | +591E-16
浮动数学和四舍五入将使您的脖子断裂,从而降低近似值的质量
您可以使用以下模块:
要获取(输入9):
我认为您打算使用zip
和range
,而不是itertools.product
,它将为您提供的两个序列的每个组合创建一个对序列
比如说,
- 产物((1,2)、(3,4))产生(1,3)、(1,4)、(2,3)和(2,4)
- 而zip((1,2),(3,4))产生(1,3)和(2,4),一个接一个地匹配位置就像一个zip
更正后的代码如下,一些注释也很有用:
def main():
n=eval(input("Enter N: "))
x,y=0,0
for i,j in zip(range(1,1+4*round((n//2)),4), range(-3,-3-4*int((n/2)),-4)):
x=x+(4/i) # sum of positive parts
y=y+(4/j) # sum of negative parts
print(x+y)
你告诉我们-你期望它做什么,它做什么,你调试了什么,可能的原因是什么?(除了缺少进口之类的东西之外)你能不能用公式正确的方式写下数字?现在,这看起来像是你想要做的(1-4)和(3+4)顺便说一句:round((n//2))
。。。整数除法已经给了你一个整数-为什么要取整呢?嗯。。我是否费心去评估浮点舍入和分数模块之间的差异。。。我想。。。稍后。不错:)@PatrickArtner:可能以后吧。我怀疑OP有那样的知识水平。对于10.000.000步,它给出了3.14159255,这可能足以说明它去了π。@PatrickArtner:这个分数的东西很奇怪。为什么差异会上下波动?我不明白。一旦你将分数“转换”回浮动状态,它将具有与普通浮动分辨率相同的限制。这样做的好处是,您不会通过将数千个“off”浮点相加来累积错误。也许在求和时浮点数的错误会相互抵消,不知道。更有趣的是,对彼此的差异应该是对一个预先计算的pi的差异,我的猜测是分数法应该比使用浮点数更适合这种误差。
Approx nr: 1) pi before: 0 approx refinement: +4 new pi:4 (4.0)
Approx nr: 2) pi before: 4 approx refinement: -4/3 new pi:8/3 (2.6666667)
Approx nr: 3) pi before: 8/3 approx refinement: +4/5 new pi:52/15 (3.4666667)
Approx nr: 4) pi before: 52/15 approx refinement: -4/7 new pi:304/105 (2.8952381)
Approx nr: 5) pi before: 304/105 approx refinement: +4/9 new pi:1052/315 (3.3396825)
Approx nr: 6) pi before: 1052/315 approx refinement: -4/11 new pi:10312/3465 (2.9760462)
Approx nr: 7) pi before: 10312/3465 approx refinement: +4/13 new pi:147916/45045 (3.2837385)
Approx nr: 8) pi before: 147916/45045 approx refinement: -4/15 new pi:135904/45045 (3.0170718)
Approx nr: 9) pi before: 135904/45045 approx refinement: +4/17 new pi:2490548/765765 (3.2523659)
3.252365934718876
def main():
n=eval(input("Enter N: "))
x,y=0,0
for i,j in zip(range(1,1+4*round((n//2)),4), range(-3,-3-4*int((n/2)),-4)):
x=x+(4/i) # sum of positive parts
y=y+(4/j) # sum of negative parts
print(x+y)