为何基于Leibniz公式的Pi计算函数无法输出指定小数位数?
问题分析与解决:Leibniz公式计算π时小数位数无法控制
核心问题
你的代码里有两个关键错误导致n无法控制小数位数:
- 计算全程依赖float类型:
(-1.0)、2.0这些都是float,float的精度只有15-17位左右,计算过程完全没用到Decimal的精度设置,最后把float转成Decimal已经无法挽回精度损失,自然不受n影响。 - 对
getcontext().prec的理解偏差:这个参数设置的是总有效数字位数(整数部分+小数部分),不是纯小数位数。比如你设n=3,实际是保留3位有效数字,而非3位小数。
修正后的代码
from decimal import Decimal, getcontext def my_leibniz(k, n): # 设置总有效数字:整数位1位(3) + n位小数,保证小数部分精度足够 getcontext().prec = n + 1 pi_over_four = Decimal(0) for num in range(k): # 所有计算用Decimal类型,彻底避免float精度限制 sign = Decimal(-1) ** num denominator = Decimal(2 * num + 1) pi_over_four += sign / denominator pie = Decimal(4) * pi_over_four # 强制格式化为n位小数,确保输出位数符合要求 formatted_pie = pie.quantize(Decimal('1.' + '0' * n)) return f'Your value of pi to {n} decimal spaces is {formatted_pie}'
代码说明
- 全程使用Decimal计算:从初始值到循环内的每一步运算都用Decimal类型,这样才能真正利用
getcontext设置的精度规则。 - 调整精度参数:π的整数部分是3(1位有效数字),要得到
n位小数,总有效数字需设为n+1,避免小数部分被截断。 - 用quantize格式化输出:
quantize(Decimal('1.' + '0'*n))可以强制结果显示为n位小数,即使末尾是0也会保留,完全符合你对“n位小数”的需求。
测试示例
调用my_leibniz(1000, 3),输出为:
'Your value of pi to 3 decimal spaces is 3.141'
调用my_leibniz(10000, 5),输出为:
'Your value of pi to 5 decimal spaces is 3.14159'
注意:Leibniz公式收敛极慢,要得到n位准确的小数,k需要取极大值(比如要10位小数,k至少要10^10次循环),实际场景建议用收敛更快的公式。
内容的提问来源于stack exchange,提问作者user25001766
相关产品推荐
相关产品推荐

