2016-11-19 7 views
1

私の平方根プログラムは何らかの理由で、ほとんどの入力に対して何を得るべきであるかというだけの答えです。なぜこのことが分かりませんか?特定の入力だけが間違っています。私はまた、答えが与えられた後、非常に最後にセグメンテーションフォルトを取得し、それがどちらかであるかどうかわからない。あなたがreturn文C++平方根と再帰

double newton(double num, double a) 
{ 


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


} 

を配置するのを忘れたので

#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

すべての警告を有効にして、コンパイラから通知された内容を確認します。そして、[なぜ "namespace stdを使うのは悪い習慣"と考えられますか?](http://stackoverflow.com/q/1452721/995714) –

+0

不正な平方根を与えるいくつかの値は何ですか? – 1201ProgramAlarm

答えて

2

関数が未定義の動作をしているがなければならない

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

あなたがargv[argc]にアクセスしようとするので、あなたがクラッシュを取得しています、これはargv配列の最後を過ぎています。

FLT_EPSILONfloatの値)と比較しているため、数字が間違っている可能性があります。は2倍に使用されます。しかし、これらのいずれかと比較することは、この問題の正しいアプローチではありません。 aの値に比例してスケールされた差異を調べる必要があります。

0

私が最初に固定されなければならない二つの基本的なエラーを参照してください。

  1. をあなたの主な機能は、リターンを持っていません。あなたの最後の}の前に、あなたの主な機能の最後にreturn 0;を置くべきです。

  2. 存在しないargv[argc]にアクセスしようとしています。その配列の最後の要素はargv[argc - 1]です。ループステートメントを変更して、配列の存在しない部分を読み込もうとしないようにしてください。

0

1201ProgramAlarmの回答に加えて、なぜ次のように悪いですか?

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

たとえば、epsは1e-15で、DBL_EPSILONより少し大きいとします。もし、aがやや大きければ(5以上のような)、最後の場所(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の平方根とする。これはひどい精度です。