Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用itertools和Leibniz级数逼近Pi值_Python - Fatal编程技术网

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)