由于某种原因,我的平方根程序得到的答案与大多数输入应该得到的结果略有不同。我不确定为什么会这样。只有某些输入是错误的。在给出答案之后,我也会在最后得到一个分段错误,并且不确定为什么会这样。
#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;
}
答案 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)
我看到应首先解决的两个基本错误:
您的主要功能没有返回。您应该在最后一个innerCirclePathLayer.strokeColor = UIColor(red: 100/255.0, green: 60/255.0, blue: 70/255.0, alpha: 0.2).cgColor
之前将return 0;
放在主要功能的末尾。
您正在尝试访问不存在的}
。该数组中最后一个现有元素是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的平方根。这是一种残酷的精确度。