【问题标题】:Recursive Newton Square Root Function Only Terminates for Perfect Squares递归牛顿平方根函数仅终止于完美平方
【发布时间】:2018-04-20 17:33:01
【问题描述】:

我编写的程序看起来与我在网上看到的其他递归牛顿平方根函数非常相似。出于某种原因,这个只适用于完美的正方形,我似乎找不到原因。我尝试传递 3 个变量(epsilon),设置 x=a,将 a = 设置为第 9 行中传递的方程,然后传递 abs(a*a-x)。我试图尽可能地描述它,这对我来说是一个稍微新的话题,我只是不确定这是否只能找到完美的根源,或者我的代码/方程式是否不正确。

 1  #include <cmath>
 2  #include <iostream>
 3  using namespace std;
 4
 5  double newtroot(double x, double a) {
 6      if (fabs(a*a - x) <= DBL_EPSILON)
 7          return a;
 8      else 
 9          return newtroot(x, fabs(a*a + x)/(2*a));
10  }
11
12  int main() {
13      cout << newtroot(9, 1) << endl;
14      system("pause");
15      return 0;
16  }

编辑:该函数不仅适用于完美正方形,而且仅适用于完美正方形。如果它不是一个完美的正方形 a 最终是正确的值(在调试器中检查)但递归永远不会停止。我认为它必须与第 6 行中的比较有关,所以我尝试用 a 替换 DBL_EPSILON 并返回不正确的值。
当输入不完美的正方形时,此错误也会显示在第 6 行:

RecursionProgrammingExcercisesMurphyT.exe 中 0x00007FFE8E9C06F0 (ucrtbased.dll) 处未处理的异常:0xC00000FD:堆栈溢出(参数:0x0000000000000001、0x00000013B2603FE8)。发生了

【问题讨论】:

    标签: recursion square-root perfect-square


    【解决方案1】:

    未检测到基本情况是由于过度乐观的解释:
    DBL_EPSILON 不是“适合终止改进任何近似值的值”,但是
    差异介于 1 和大于 1 的可表示的最小值之间
    它需要缩放以限制相对错误。
    return (fabs(approx*approx - x) &lt;= 2*x*DBL_EPSILON) ? approx
            : newtroot(x, fabs(approx*approx + x)/(2*approx));
    当一个近似值足够快可以容忍数值错误时,终止它的一个有希望的方法是检查新的近似值既不是当前的也不是以前的。

    /*! approximate the value of x**.5 */
    double newtroot(double x, double approx, double previous) {
        double next = fabs(approx*approx + x)/(2*approx);
        return next == approx || next == previous
            ? approx : newtroot(x, next, approx);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 2014-03-07
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      相关资源
      最近更新 更多