带递归的C ++ Square Root

时间:2016-11-19 04:16:47

标签: c++ recursion

由于某种原因,我的平方根程序得到的答案与大多数输入应该得到的结果略有不同。我不确定为什么会这样。只有某些输入是错误的。在给出答案之后,我也会在最后得到一个分段错误,并且不确定为什么会这样。

#include<iostream>
#include<cmath>
#include<cfloat>
#include<string>
#include <cstdlib>
using namespace std;

//declare sqroot function calls recursive function newton
double sqroot1(double num );
double newton(double num, double guess);
int main(int argc, char **argv)
{

    for( int i = 0 ; i < argc ; i++)
    {
       cout<<"sqroot("<<argv[i+1]<<") is "<< sqroot1(atoi(argv[i+1]))     <<endl;
    }
}

double newton(double num, double a)
{
    if ((abs(a*a - num) <= FLT_EPSILON))
    {
        return a;
    }
    else
    {
        newton(num, (a+num/a)/2 );
    }
}

double sqroot1(double num)
{
    double sqrt = newton(num,num/2);
    return sqrt;
}

4 个答案:

答案 0 :(得分:2)

该函数具有未定义的行为,因为您忘记放置return语句

double newton(double num, double a)
{


    if ((abs(a*a - num) <= FLT_EPSILON))
    {
        return a;
    }
    else
    {
        newton(num, (a+num/a)/2 );
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }


}

必须有

    return newton(num, (a+num/a)/2 );

答案 1 :(得分:1)

您遇到了崩溃,因为您尝试访问argv[argc]数组的末尾argv

您的号码可能已关闭,因为您正在与FLT_EPSILON进行比较,这是float值。 DBL_EPSILON用于双打。但是,与其中任何一个相比,这不是解决此问题的正确方法。您需要检查相对于a值缩放的差异。

答案 2 :(得分:0)

我看到应首先解决的两个基本错误:

  1. 您的主要功能没有返回。您应该在最后一个innerCirclePathLayer.strokeColor = UIColor(red: 100/255.0, green: 60/255.0, blue: 70/255.0, alpha: 0.2).cgColor 之前将return 0;放在主要功能的末尾。

  2. 您正在尝试访问不存在的}。该数组中最后一个现有元素是argv[argc]。尝试更改循环语句,以便它不会尝试读取数组中不存在的部分。

答案 3 :(得分:0)

添加到1201ProgramAlarm的答案,为什么以下情况如此糟糕?

if ((abs(a*a - num) <= eps))

让我们说eps是1e-15,比DBL_EPSILON大一点。好吧,如果a甚至是中等大(类似于5或更大),那么a*a的最后一个位置(ulp)的单位大于eps和条件只有a*a == num才能成立。有一个风险,有四舍五入,这不会达到,你最终会得到无限的递归和崩溃。

现在让我们说num非常小,以便初步猜测

abs(num/2*num/2 - num) <= eps

例如,sqroot1(1e-20)将评估

abs(1e-40/4 - 1e-20)   <= 1e-15

这是真的,你会得到5e-21作为1e-20的平方根。这是一种残酷的精确度。