C#计算π前n位数字:Decimal.Precision设置及结果输出求助
计算π前n位数字的C#代码问题解决
核心问题梳理
你当前代码存在几个关键问题:
- C#中不存在
System.Decimal.Precision属性,decimal类型的有效精度固定为28-29位,无法通过该方式修改; - π计算公式仅迭代了
k=0的单一项,精度完全不足以支撑多位数字计算; - 阶乘计算使用
decimal会快速溢出,无法处理较大的k值; - 未实现指定n位数字的输出逻辑。
解决方案与代码修正
1. 替换阶乘计算类型为BigInteger
阶乘增长极快,decimal很快就会溢出,改用BigInteger可支持更大数值的计算:
static BigInteger Factorial(int n) { if (n == 0) return BigInteger.One; return n * Factorial(n - 1); }
2. 迭代足够多的k值以获取目标精度
使用Chudnovsky算法(你当前代码的基础算法)需要迭代多个k值,直到新增项对结果的影响小于目标精度:
BigInteger sum = BigInteger.Zero; int k = 0; decimal targetEpsilon = (decimal)Math.Pow(10, -(n + 2)); // 预留两位冗余精度避免截断误差 do { BigInteger t = Factorial(6 * k) * (13591409 + 545140134 * k); BigInteger deno = Factorial(3 * k) * BigInteger.Pow(Factorial(k), 3) * BigInteger.Pow(640320, 3 * k); sum += t / deno; k++; decimal currentTerm = (decimal)t / deno; } while (Math.Abs(currentTerm) > targetEpsilon);
3. 实现指定n位数字的输出
decimal仅支持28-29位精度,若需求在该范围内,可通过格式化字符串输出指定位数:
// 计算π值 decimal pi = 12m * (decimal)sum / (decimal)BigInteger.Pow(640320, 3 * k / 2); pi = 1 / pi; // 格式化输出前n位,自动去除末尾多余的0和小数点 string result = pi.ToString($"F{n}").TrimEnd('0').TrimEnd('.'); Console.WriteLine($"π的前{n}位数字:{result}");
完整修正代码
using System; using System.Numerics; namespace PiCalculator { class Program { static void Main(string[] args) { Console.WriteLine("How Many Digit?"); if (!int.TryParse(Console.ReadLine(), out int n) || n <= 0) { Console.WriteLine("请输入有效的正整数"); return; } BigInteger sum = BigInteger.Zero; int k = 0; decimal targetEpsilon = (decimal)Math.Pow(10, -(n + 2)); do { BigInteger t = Factorial(6 * k) * (13591409 + 545140134 * k); BigInteger deno = Factorial(3 * k) * BigInteger.Pow(Factorial(k), 3) * BigInteger.Pow(640320, 3 * k); sum += t / deno; k++; decimal currentTerm = (decimal)t / deno; } while (Math.Abs(currentTerm) > targetEpsilon); decimal pi = 12m * (decimal)sum / (decimal)BigInteger.Pow(640320, 3 * k / 2); pi = 1 / pi; string result = pi.ToString($"F{n}").TrimEnd('0').TrimEnd('.'); Console.WriteLine($"π的前{n}位数字:{result}"); } static BigInteger Factorial(int n) { if (n == 0) return BigInteger.One; return n * Factorial(n - 1); } } }
额外说明
- 若需要计算超过28位的π值,
decimal精度不足以支撑,建议使用专门的高精度数值库(如MathNet.Numerics); - Chudnovsky算法收敛速度极快,通常迭代几十次就能得到上千位π值,核心是用
BigInteger避免大数值溢出。
内容的提问来源于stack exchange,提问作者EGO
相关产品推荐
相关产品推荐

