为何基于牛顿-拉夫逊法的平方根近似程序陷入死循环?
问题分析与修复:牛顿-拉夫逊法求平方根无限循环问题
首先,你的推测(公式缺少括号)其实不是问题核心——牛顿-拉夫逊迭代公式x = x/2 + a/(2*x)是正确的,括号使用没问题。真正导致无限循环的原因是循环退出条件写错了!
错误点详解
看你SquareRoot方法里的循环判断:
double val = x * x; if (Math.Abs(a) <= error) return x;
这里你判断的是原始输入a的绝对值是否小于误差阈值error,这完全不符合逻辑——除非输入的a本身就是小于0.00001的数,否则这个条件永远不会成立,循环就会一直跑下去。
正确的退出条件应该是:当前迭代得到的x的平方与目标数a的差值的绝对值,小于设定的误差阈值,也就是判断Math.Abs(val - a) <= error。
另外还有两个小细节需要修正:
- 方法名拼写错误:
SqaureRoot应该是SquareRoot(主函数里的调用和方法定义要保持一致) - 当输入
a=0时,初始值x=1会导致不必要的迭代,建议优化初始值来适配不同输入情况。
修复后的完整代码
主函数:
public static void Main(string[] args) { Console.WriteLine("Enter number to find Square Root"); var num = Convert.ToInt32(Console.ReadLine()); var ans = SquareRoot(num); // 修正方法名拼写 Console.WriteLine("Square root of {0} : {1}", num, ans); }
SquareRoot方法:
public static double SquareRoot(double a) { if (a < 0) throw new Exception("Can not sqrt a negative number"); double error = 0.00001; // 优化初始值:适配a>=1和a<1的情况,避免无效迭代 double x = a >= 1 ? a / 2 : 1; while (true) { double val = x * x; // 正确的退出条件:判断当前x的平方与a的差值是否在误差范围内 if (Math.Abs(val - a) <= error) return x; // 牛顿-拉夫逊迭代公式,此处写法正确 x = x / 2 + a / (2 * x); } }
验证说明
修复后,程序会在迭代到x²与a的误差小于0.00001时退出循环,返回近似的平方根值。比如输入25,会很快收敛到5.0左右的结果;输入2,会得到1.4142左右的正确近似值。
内容的提问来源于stack exchange,提问作者James Michael
相关产品推荐
相关产品推荐

