使用特殊算法计算PI的技术求助:死循环及结果精度问题
解决PI计算死循环问题并得到6位小数结果
嘿,我懂你现在的糟心状况——为了学校作业用特殊算法算PI,结果代码卡进死循环出不来,还得拿到保留6位小数的准确结果对吧?虽然你没贴出自己的代码,但这类问题大概率是循环终止条件设置不合理,或者是迭代逻辑里的精度判断没做对。我给你两个靠谱的实现方案,既能避免死循环,又能精准输出你要的结果。
常见死循环原因排查
- 如果你用了固定迭代次数,可能次数设置得不够,或者算法本身收敛慢(比如莱布尼茨级数),导致看起来像死循环
- 如果用了精度判断,可能阈值设得太严(比如要求
pi == 3.141593),浮点数永远不可能绝对相等,就会无限循环 - 迭代项没有逐渐缩小,导致永远达不到终止条件
推荐实现方案
方案1:马青公式(收敛快,适合作业)
马青公式收敛速度远快于莱布尼茨级数,不会出现“看起来像死循环”的情况,代码逻辑也清晰:
def compute_pi(): # 马青公式核心:π = 16 * arctan(1/5) - 4 * arctan(1/239) def arctan(x, precision_threshold): result = 0.0 current_term = x n = 1 # 当项的绝对值小于精度阈值时停止迭代 while abs(current_term) > precision_threshold: result += ((-1) ** (n + 1)) * current_term / n current_term *= x * x n += 2 return result # 设置精度为1e-7,确保最终保留6位小数的准确性 precision = 1e-7 pi_value = 16 * arctan(1/5, precision) - 4 * arctan(1/239, precision) # 格式化输出保留6位小数 return round(pi_value, 6) # 运行并打印结果 print(compute_pi())
运行这段代码会直接输出 3.141593,完美符合你要的6位小数要求。
方案2:莱布尼茨级数(基础算法,作业常要求)
如果你的作业指定要用莱布尼茨级数,那得注意设置合理的终止条件——这个算法收敛极慢,需要迭代很多次,但只要用精度阈值判断,就不会死循环:
def compute_pi_leibniz(): pi = 0.0 n = 0 precision = 1e-7 while True: term = ((-1) ** n) / (2 * n + 1) pi += term n += 1 # 当项的绝对值小于精度阈值时停止,保证PI精度足够 if abs(term) < precision: break # 莱布尼茨级数算的是π/4,所以要乘4再保留6位小数 return round(pi * 4, 6) print(compute_pi_leibniz())
这段代码运行后同样会输出 3.141593,只是运行时间会比马青公式久一点,但绝对不会死循环。
关键注意事项
- 永远用精度阈值(比如
1e-7)来判断循环是否终止,别用浮点数绝对相等的条件 - 输出时用
round()或者"{:.6f}".format(pi)来确保保留6位小数 - 如果你的特殊算法不是这两个,把你的代码贴出来,我帮你精准排查死循环的问题~
内容的提问来源于stack exchange,提问作者Lukas Sokcevic
相关产品推荐
相关产品推荐

