2016-09-27 6 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 루프가 무한대로 생성됩니다. 형식 '% e'는 'double'형식의 인수를 예상하지만 인수 5는 'int'[-Wformat] 형식을 갖는 경고가 표시됩니다. 왜 이런거야?while 루프가 무한 이유가 무엇입니까?

답변

4

calcError 항상 0 반환, 그래서

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

while(0 < 1e-6) 

또는 경고에 관해서는

while(true) 

이 컴파일러는 잘못을 정확하게 말한다 좋은과 같습니다 calcError 반환 int이지만 사용자가 제공 한 형식 문자열 ( %e)은 double이 필요합니다. 이렇게하면 정의되지 않은 동작이 발생합니다. 아래와 같이 반환 유형을 변경하면이 문제가 해결됩니다.

코드를 보면 오류가 1e-6보다 큰 경우 루프를 실행하고 싶다고 생각합니다. 맞습니다 경우 다음과 같이 할 수 있도록 calcError을 수정할 수 있습니다

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() 기능에
while(calcError(n,r) > 1e-6) 
+0

감사합니다. 그러나 해당 변경 내용으로 코드를 실행해도 동일한 경고가 생성됩니다. 더 이상 무한 루프가 아니라 더 이상 while 루프를 완전히 우회하여 다음과 같이 표시합니다 : sqrt (24.000000) = 24.000000 to six places – normystar

+1

오류가 엡실론보다 큰 경우 반복 할 것입니다. this :'while (calcError (n, r)> 1e-6) ' – krzaq

+0

[this] (http://melpon.org/wandbox/permlink/Oqw54hodZugBWEnn)이 당신이 원했던 것입니다. 그건 그렇고,'printf'에 대한'calcError'의 호출은 역순으로 인수를가집니다. – krzaq

0

, 당신은이

return 0; 

따라서 식에서는 calcError()이 항상 0입니다.

(0 < 1e-6)은 항상 true입니다.

0

당신은 while(calcError(n,r)<1e-6)이고 calcError은 항상 0을 반환하므로 물론 루프가 영원히 계속 될 것입니다. 제 생각 엔 calcError0 대신에 delta이 되려는 것 같습니다.

관련 문제