计算平方根时出现SegFault错误(牛顿法) [英] SegFault error when computing square root (Newton's method)

查看:74
本文介绍了计算平方根时出现SegFault错误(牛顿法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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...)

  1. 没有理由让您的例行程序递归.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆