关于泰勒级数计算函数值的任务理解及代码问题咨询
问题与解答
任务要求
在区间[Xstart,Xend]内,以步长dx、精度E为标准,采用泰勒级数计算指定函数的值,并以表格形式在屏幕展示。表格需包含表头,每行需列出自变量值、函数值及级数求和项数。对应的泰勒级数为$\ln x$的特殊展开形式:
$$\ln x = \sum_{n=1}^{\infty} \frac{1}{n} \left( \frac{x-1}{x} \right)^n$$
该级数收敛条件为$x > 0.5$。
用户疑问与代码
我看不懂左边的$\ln x$对应的泰勒级数,这看起来不是我知道的$\ln x$泰勒级数。我写了下面的C#代码,但还是没完全搞懂任务要求,希望得到帮助:
using System; namespace LabWorks1k2s { internal class Program { static void Main() { double y, xmin, xmax, dx, e; int n, nmax; string buf; do { Console.WriteLine("x start: "); buf = Console.ReadLine(); xmin = Convert.ToDouble(buf); } while (xmin < 0.5); do { Console.WriteLine("x end: "); buf = Console.ReadLine(); xmax = Convert.ToDouble(buf); } while (xmax < 0.5); Console.WriteLine("dх: "); buf = Console.ReadLine(); dx = Convert.ToDouble(buf); Console.WriteLine("Iterations: "); buf = Console.ReadLine(); nmax = Convert.ToInt32(buf); Console.WriteLine("accuracy e: "); buf = Console.ReadLine(); e = Convert.ToDouble(buf); n = 0; double sum = 0; Console.WriteLine("Arg\t Func\t N"); while (xmin<=xmax) { do { y = Math.Pow((xmin - 1), n + 1) / (n + 1) * Math.Pow(xmin, n + 1); sum = sum + y; n++; xmin += dx; Console.WriteLine("{0}\t{1,50}\t{2}", xmin, sum, n); if (n>=nmax) { Console.WriteLine("Too much iterations!"); break; } } while (Math.Abs(sum) >= e); } Console.ReadKey(); } } }
泰勒级数解释
你看到的是$\ln x$的非标准泰勒展开形式,它通过变量替换推导而来:令$t = \frac{x-1}{x}$,则$x = \frac{1}{1-t}$,代入$\ln x = -\ln(1-t)$的级数展开($\ln(1-t) = -\sum_{n=1}^\infty \frac{t^n}{n}$),就能得到这个级数。它的收敛区间是$x > 0.5$,这也是你代码里限制输入x大于0.5的原因。
代码问题分析
- 级数项计算错误:你写的
y = Math.Pow((xmin - 1), n + 1) / (n + 1) * Math.Pow(xmin, n + 1);完全错误,正确项应为$\frac{1}{n} \times \left( \frac{x-1}{x} \right)^n$,即Math.Pow((currentX - 1)/currentX, n) / n,你把分母的$x^n$写成了乘法,逻辑完全颠倒。 - 变量迭代逻辑错误:在循环中,你每次计算一项就执行
xmin += dx,导致单个x值还没完成级数求和就跳到下一个x,正确逻辑是先对当前x计算到满足精度,再更新x到下一个步长。 - 求和状态未重置:每个x的级数求和应该重新初始化
sum和n,否则上一个x的累加结果会干扰当前x的计算。 - 终止条件错误:你用
Math.Abs(sum) >= e作为循环终止条件,这不符合泰勒级数的收敛判断逻辑——应该判断当前新增项的绝对值小于精度E,因为当新增项足够小时,累加和的误差就满足要求了。
修正后的代码
using System; namespace LabWorks1k2s { internal class Program { static void Main() { double xStart, xEnd, dx, e; int nMax; string input; // 输入x起始值,验证合法性 do { Console.Write("请输入x起始值(>0.5):"); input = Console.ReadLine(); } while (!double.TryParse(input, out xStart) || xStart <= 0.5); // 输入x结束值,验证合法性 do { Console.Write("请输入x结束值(>0.5且≥起始值):"); input = Console.ReadLine(); } while (!double.TryParse(input, out xEnd) || xEnd <= 0.5 || xEnd < xStart); // 输入步长dx,验证合法性 do { Console.Write("请输入步长dx(>0):"); input = Console.ReadLine(); } while (!double.TryParse(input, out dx) || dx <= 0); // 输入最大迭代次数,验证合法性 do { Console.Write("请输入最大迭代次数nMax(>0):"); input = Console.ReadLine(); } while (!int.TryParse(input, out nMax) || nMax <= 0); // 输入精度E,验证合法性 do { Console.Write("请输入精度E(>0):"); input = Console.ReadLine(); } while (!double.TryParse(input, out e) || e <= 0); // 打印格式化表头 Console.WriteLine("\n| 自变量x | 函数值lnx | 求和项数n |"); Console.WriteLine("|-----------|-----------|-----------|"); // 遍历区间内的每个x double currentX = xStart; while (currentX <= xEnd + 1e-10) // 处理浮点数精度误差 { double sum = 0; int n = 0; bool maxIterReached = false; double currentTerm; do { n++; // 计算当前级数项 double ratio = (currentX - 1) / currentX; currentTerm = Math.Pow(ratio, n) / n; sum += currentTerm; // 检查是否达到最大迭代次数 if (n >= nMax) { maxIterReached = true; break; } } while (Math.Abs(currentTerm) >= e); // 当项的绝对值小于精度时停止 // 打印当前x的结果 Console.WriteLine($"| {currentX,9:F6} | {sum,9:F6} | {n,9} |"); if (maxIterReached) { Console.WriteLine($" 警告:x={currentX:F6}已达最大迭代次数,未满足精度要求"); } // 更新到下一个x currentX += dx; } Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); } } }
修正说明
- 修正了级数项的计算逻辑,严格对应给定的泰勒展开式
- 每个x值单独初始化求和变量,避免跨x的状态污染
- 调整终止条件为判断当前项的绝对值小于精度E,符合数值计算的收敛判断标准
- 增加了输入合法性验证,使用
TryParse避免格式错误导致的程序崩溃 - 优化了输出格式,使用对齐的表格提升可读性
- 处理了浮点数精度问题,避免因步长累加误差导致循环提前终止或无限循环
内容的提问来源于stack exchange,提问作者black_swordsman3351
相关产品推荐
相关产品推荐

