c# - 使用带有递归 c# 的牛顿法的平方根
问题描述
我正在尝试计算数字 12345 的平方根。我是编程新手,需要底部帮助,所以我没有收到异常“堆栈溢出”。
public static decimal Sqrt(int number, decimal root)
{
return Sqrt(number, root - ((root * root) - number) / (2 * root));
}
static void Main(string[] args)
{
decimal root = Sqrt(12345, 10M);
Console.WriteLine(root);
}
解决方案
维基百科:
堆栈溢出的最常见原因是过深或无限递归,其中函数调用自身的次数太多,以至于存储与每次调用相关的变量和信息所需的空间超出了堆栈的容量。
C中无限递归的一个例子。
int foo()
{
return foo();
}
函数 foo 在调用时会继续调用自己,每次都会在堆栈上分配额外的空间,直到堆栈溢出导致分段错误。然而,一些编译器实现了尾调用优化,允许特定排序的无限递归——尾递归——发生而没有堆栈溢出。这是因为尾递归调用不占用额外的堆栈空间。
你错过了一张支票。您的代码是无限递归的,因为没有办法摆脱递归。
线
return Sqrt(number, root - ((root * root) - number) / (2 * root));
将导致另一个Sqrt
方法调用,它会导致另一个Sqrt
方法调用,这将导致 .... SO 当它停止并返回正确的结果?!
无论如何,如果您添加一个 if 语句,它将正常工作。
public static decimal Sqrt(int number, decimal root)
{
if (Math.Abs(root * root - number) <= 0.00000000001M)
return root;
return Sqrt(number, root - ((root * root) - number) / (2 * root));
}
// Usage:
static void Main(string[] args)
{
Console.WriteLine(Sqrt(4, someDecimal));
}
如果你使用
if (root * root == number)
代替
if (Math.Abs(root * root - number) <= 0.00000000001M)
,您的代码将只支持完美的正方形。
推荐阅读
- html - 菜单打开时如何更改字体真棒图标的颜色?
- c# - 如何使用 Bouncy Castle 从 URL 读取 C# 中的 DER 扩展文件
- javascript - 尝试登录时出现错误 [ERR_INVALID_ARG_TYPE]
- gradle - 我们应该在回购中包含`.gradle`吗?
- python - 不和谐频道制造商
- flutter - 如何修复 Flutter 中的异常“一旦你调用了 dispose()...”
- protractor - 量角器:读取表格内容
- node.js - 在 AWS ElasticBeanstalk 上部署具有 bcrypt 依赖项的节点应用程序失败
- group-by - Python:按唯一 ID 分组的分块数据的并行化
- python - Python heapq 优先队列 Maxheap