2016-09-27 16 views
0
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 

if (argc != 2) { 
    printf("Too many arguments.\n", argc); 
return 1; 
} 

double n; 
n = atof(argv[1]); 

if (n<0) { 
    printf("Negative argument.\n"); 
return 1; 
} 

double r; 
r = n; 
int iteration; 
iteration = 0; 

while(calcError(n,r)<1e-6) { 
    iteration = iteration +1; 
    r = (r + n/r)/2; 
    printf(" %d. sqrt(%f)~= %f,error=%e\n",iteration,n,r,calcError(r,n)); 
} 

printf("sqrt(%f)=%f to six places\n",n,r); 

return 0; 
} 

int calcError (double n, double r) { 

double delta; 

delta = n-r*r; 
delta = delta > 0 ? delta : -delta; 

return 0; 

} 

このコードを実行すると、whileループが無限に生成されます。 format '%e'は 'double'型の引数を期待していますが、引数5は 'int' [-Wformat]の型を持っています。どうしてこれなの?なぜwhileループが無限ですか?

答えて

4

calcErrorはいつも

while(calcError(n,r)<1e-6) 

が警告については

while(0 < 1e-6) 

または

while(true) 

と同様に良好である、0を返し、コンパイラが間違っている正確に何と言う:calcErrorリターンをintであるが、あなたが提供するフォーマット文字列(%e)にはdoubleが必要です。これにより、未定義の動作が生成されます。以下のように戻り値の型を変更すると、この問題が解決されます。

コードを見ると、エラーが1e-6より大きい限り、ループしたいと思うと思います。

double calcError(double n, double r) 
{ 
    return fabs(n-r*r); 
} 

に短縮し、それが小さくなるまでループにあなたのループの条件を変更することができます

int calcError (double n, double r) 
{ 
    double delta; 

    delta = n-r*r; 
    delta = delta > 0 ? delta : -delta; 
    return delta; 
} 

をそれが正しいなら、あなたは以下のようにあなたの calcErrorを変更したい場合がありますあなたが持っているあなたの calcError()機能で
while(calcError(n,r) > 1e-6) 
+0

ありがとうございました。ただし、その変更でコードを実行すると、同じ警告が生成されます。もはや無限ループではなく、whileループを完全にバイパスして次のように表示します:sqrt(24.000000)= 24.000000 to six places – normystar

+1

エラーがあなたのイプシロンより大きい限りループしたいと思います。これは:while(calcError(n、r)> 1e-6) ' – krzaq

+0

私はかなり[this](http://melpon.org/wandbox/permlink/Oqw54hodZugBWEnn)があなたの望むものであると確信しています。ちなみに、 'printf'に対する' calcError'の呼び出しには逆の引数があります。 – krzaq

0

return 0; 

あなたの式では、calcError()は常にゼロになります。

および(0 < 1e-6)は常にtrueです。

0

あなたはwhile(calcError(n,r)<1e-6)calcErrorは常に0を返すので、もちろんあなたのループは永遠に続くでしょう。私はあなたが0の代わりにの返信deltaを持つことを意味すると思う。

関連する問題