计算平方根时出现SegFault错误(牛顿法) [英] SegFault error when computing square root (Newton's method)
问题描述
我对C ++还是很陌生,但是我知道有很多方法可以接收到SegFault错误,但是我不确定为什么会在这里出现错误.该程序的目标是使用牛顿法计算数字的平方根.我假设它与递归有关,但是我很确定代码将在Java中运行.
I'm very new to C++, but I'm aware that there are tons of ways to receive a SegFault error, but I'm not sure why I'm getting one here. The goal of the program is to compute the square root of a number using Newton's method. I'm assuming it has something to do with the recursion, but I'm pretty sure that the code would run in Java.
#include <iostream>
#include <sstream>
using namespace std;
double sqrt(double eps, double num, double last_guess)
{
if(num == 0 || num == 1)
{
return num;
}
int next = (num + (num/last_guess)) / 2;
if(abs(last_guess - next) <= eps)
return next;
else
return sqrt(eps, num, next);
}
int main(int argc, char *argv[]) {
double eps, num;
istringstream iss; //input string
if(argc == 3)
{
iss.str(argv[1]);
if ( !(iss >> eps) ) {
cerr << "Error: The first argument is not a valid double." << endl;
return 1;
}
iss.clear();
iss.str(argv[2]);
if ( !(iss >> num) ) {
cerr << "Error: The second argument is not a valid double." << endl;
return 1;
}
} else if(argc == 2) {
iss.str(argv[1]);
if ( !(iss >> num) ) {
cerr << "Error: Argument is not a valid double." << endl;
return 1;
}
eps = 0.000001;
}
cout << "sqrt(" << eps << ", " << num << ") = " << sqrt(eps,num, num) << endl;
return 0;
}
示例输入:0.000001 4.0
Sample input: 0.000001 4.0
推荐答案
在GDB下运行程序表明它是无限递归的:
Running your program under GDB shows that it is in infinite recursion:
(gdb) run
Starting program: /tmp/a.out 0.000001 4.0
Program received signal SIGSEGV, Segmentation fault.
0x000055555555522d in sqrt (eps=<error reading variable: Cannot access memory at address 0x7fffff7feff8>,
num=<error reading variable: Cannot access memory at address 0x7fffff7feff0>, last_guess=<error reading variable: Cannot access memory at address 0x7fffff7fefe8>) at foo.cc:7
7 {
(gdb) bt 20
#0 0x000055555555522d in sqrt (eps=<error reading variable: Cannot access memory at address 0x7fffff7feff8>,
num=<error reading variable: Cannot access memory at address 0x7fffff7feff0>, last_guess=<error reading variable: Cannot access memory at address 0x7fffff7fefe8>) at foo.cc:7
#1 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#2 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#3 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#4 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#5 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#6 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#7 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#8 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#9 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#10 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#11 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#12 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#13 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#14 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#15 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#16 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#17 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
#18 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=2) at foo.cc:19
#19 0x00005555555552df in sqrt (eps=9.9999999999999995e-07, num=4, last_guess=3) at foo.cc:19
(More stack frames follow...)
-
没有理由让您的例行程序递归.
There is no reason to make your routine recursive.
您的算法无法识别(缺少检查)您已经计算出正确答案.
Your algorithm fails to recognize (is missing a check) that you've already computed the correct answer.
您不应该将您的猜测与epsilon之间的差异进行比较.您应该将计算出的答案与实际答案之间的差异进行比较.
You shouldn't compare the delta between your guesses to the epsilon. You should compare the delta between your computed answer and the real answer instead.
正如@PaulMcKenzie所指出的那样,您不应将连续的近似值存储为整数(而是使用 double
).
As @PaulMcKenzie noted, you shouldn't store your successive approximations in a integer (use double
instead).
要更正程序,您需要在下一个猜测中使用正确的公式:
To correct the program, you need to use correct formula for the next guess:
double next = (last_guess + (num/last_guess)) / 2;
这篇关于计算平方根时出现SegFault错误(牛顿法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!