基于巴塞尔问题的Python圆周率计算程序输出异常及精度停滞问题
你的巴塞尔问题π计算程序的问题解析
让我们一步步拆解你遇到的两个问题:
1. 初始程序无输出:变量名拼写错误导致死循环
看你代码里的外层循环条件:
outerrepeat=1000000 while outerrepat>0: # 这里拼错了!应该是outerrepeat
你定义的循环控制变量是outerrepeat,但循环条件里写成了outerrepat(少了一个字母'e')。这会直接导致程序陷入死循环——永远重复执行嵌套的内层循环,根本到不了最后的print语句,自然没有任何输出。你后来把print移到外层循环后能运行,应该是顺便修正了这个拼写错误,让循环能正常递减结束。
2. 结果停止收敛:浮点数精度的限制
你的程序用的是Python默认的float类型(sqrt=1.、sumn=0.都是float),而float的精度只有15-17位有效数字。
巴塞尔问题的核心是累加1/n²直到足够多的项,最终通过π = sqrt(6 * sum(1/n²))计算圆周率。但当n(也就是你的sqrt变量)足够大时,1/n²的值会小到无法被float的精度捕捉:比如当n≈1e8时,1/n²=1e-16,而此时sum(1/n²)的值已经接近π²/6≈1.6449,float类型无法区分这个值加上1e-16后的变化,所以sumn不再增加,后续的累加完全无效,导致计算出的π值停止收敛。
解决办法:使用高精度小数类型
你已经导入了decimal模块,但没用到它。可以用decimal.Decimal来设置更高的精度,这样就能捕捉到更小的累加项,让结果继续收敛:
import decimal # 设置精度为50位(可以根据需要调整) decimal.getcontext().prec = 50 sqrt = decimal.Decimal(1) sumn = decimal.Decimal(0) outerrepeat = 1000000 while outerrepeat > 0: repeat = 10000 while repeat > 0: sumn += 1 / (sqrt ** 2) sqrt += 1 repeat -= 1 outerrepeat -= 1 # 计算平方根并输出 pi = (sumn * decimal.Decimal(6)).sqrt() print(pi)
不过要注意:巴塞尔问题的收敛速度本身很慢,要得到π的更多小数位,需要非常多的累加项,运行时间会很长。如果追求更快的收敛,可以考虑用其他收敛速度更快的π计算级数(比如丘德诺夫斯基算法)。
内容的提问来源于stack exchange,提问作者Elvez The Elf
相关产品推荐
相关产品推荐

