如何基于迭代次数动态调整Python圆周率输出的小数位数
解决动态格式化π结果的问题
我明白你想用Ramanujan公式计算π,并且根据迭代次数动态调整输出的小数位数——这个需求很合理,毕竟Ramanujan公式收敛极快,迭代次数越多精度越高,没必要在迭代次数少的时候输出过多小数位。
你之前遇到的问题是Python的旧式字符串格式化(%操作符)不支持直接在格式串里用变量作为精度参数,比如%a.bf这种写法是不合法的。下面给你两种正确的实现方式,再补上完整的Ramanujan公式计算函数:
方法1:使用f-string(推荐,Python 3.6+)
f-string是Python最简洁直观的格式化方式,支持直接在格式表达式中嵌入变量,完美适配你的动态精度需求:
import math def calculate_pi(k): # Ramanujan公式计算π,迭代k次(从n=0到n=k-1) sum_total = 0.0 sqrt_2 = math.sqrt(2) for n in range(k): numerator = math.factorial(4 * n) * (1103 + 26390 * n) denominator = (math.factorial(n) ** 4) * (396 ** (4 * n)) sum_total += numerator / denominator pi = 1 / ((2 * sqrt_2 / 9801) * sum_total) return pi while True: try: k = int(input("How many iterations do you want? ")) if k <= 0: print("Please enter a positive integer!") continue # 迭代k次,设置小数位数为k*10(可根据实际收敛速度调整) num_digits = k * 10 result = calculate_pi(k) # f-string动态设置小数位数 print(f'result = {result:.{num_digits}f}') except ValueError: print("Invalid input! Please enter an integer.")
方法2:使用旧式%格式化
如果需要兼容Python 3.5及更早版本,可以用%.*f的写法,其中*会读取后面的参数作为小数位数:
import math def calculate_pi(k): sum_total = 0.0 sqrt_2 = math.sqrt(2) for n in range(k): numerator = math.factorial(4 * n) * (1103 + 26390 * n) denominator = (math.factorial(n) ** 4) * (396 ** (4 * n)) sum_total += numerator / denominator pi = 1 / ((2 * sqrt_2 / 9801) * sum_total) return pi while True: try: k = int(input("How many iterations do you want? ")) if k <= 0: print("Please enter a positive integer!") continue num_digits = k * 10 result = calculate_pi(k) # 旧式格式化:*接收num_digits作为小数位数 print('result = %.*f' % (num_digits, result)) except ValueError: print("Invalid input! Please enter an integer.")
补充说明:
- Ramanujan公式的收敛速度极快,每迭代一次大约能增加14位有效数字,所以你设置
num_digits = k*10是比较保守的,也可以改成k*14来匹配实际精度; - 加入了输入校验,防止用户输入非整数或负数,让程序更健壮;
math.factorial会处理大数计算,但当k很大时(比如k>20),阶乘会变得非常大,不过Python支持任意精度整数,所以不用担心溢出问题。
内容的提问来源于stack exchange,提问作者CZP3
相关产品推荐
相关产品推荐

