2014-10-10 44 views
0

我正在爲C大學做這個任務,應該相當簡單,但其中的循環似乎不會終止,因此代碼將無法正常工作;即使我放入一個i值來限制它循環的次數。用for循環也試過了,還是卡住了。爲什麼循環不會終止,即使重複的'我'限制值?

該代碼應該考慮係數的值,並通過找到兩個大值之間的中點並試圖找出它是否爲0,如果不是,則嘗試找出三次方程的根,它應該將其中一個限制改爲中點值。這裏的相關代碼:

int main (void) 

{ 

    int i, u=1000, l=-1000; 
    float a, b, c, d, mid, y; 

    scanf(" %f %f %f %f", &a, &b, &c, &d); 

    while (abs(u - l) > 0.001 && i < 10) 
    { 
     mid= (u + l)/2; 
     y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d; 

     if(y == 0) break; 
     else if(y < 0) l = mid; 
     else u = mid; 

     i++; 
    } 
    printf("\nThere is a root at: x = %.3f\n", mid); 
} 

任何幫助,將不勝感激,謝謝!

編輯:哦,我的上帝,我是個白癡。總是小事。該代碼仍然無法正常工作,但至少不會卡住,謝謝你們!

+3

「i」的初始值是多少?因爲如果它等於-100000什麼的,需要很長時間才能達到10. – AntonH 2014-10-10 21:26:10

+1

調試器可以幫助你找到這些東西。或者只是'printf(「%i \ n」,我);'在那裏,它會告訴你出了什麼問題。 – Almo 2014-10-10 21:28:37

+0

如果答案對您有幫助,如果您選擇接受答案,我們將不勝感激。有關詳細信息,請參見[本頁](http://stackoverflow.com/help/someone-answers)。 – abelenky 2014-10-10 21:49:54

回答

0

2件事。將我初始化爲0.這將確保它在10個循環後終止。 雖然對你的問題更重要,但你已經將u和l聲明爲整數,我認爲你需要將它們聲明爲浮點數。

0

需要初始化iint i = 0;

1

你宣佈i,但沒有初始化它,所以它被設置爲被保留在內存中的任何隨機值。

對於這個例子,可以說這個值是-12,345

然後i在它大於10之前可以增加12,000次以上! 當我遞增12,355次時,你的循環將運行,並且它的值變爲10,並且測試i < 10最終失敗。

爲了解決這個問題,初始化i = 0

int i=0; 
+0

你的意思是,所以讀它是未定義的行爲? – Deduplicator 2014-10-10 22:01:18

+0

未定義的行爲意味着任何事情都可能發生,包括格式化磁盤或從串口出現惡魔。我做*不*認爲這是一個未定義的行爲情況。相反,我相信這是明確的,你會從'我'得到一些*有效的整數;你無法預測它會是什麼樣的價值。 沒有惡魔的危險。 – abelenky 2014-10-10 22:04:12

+0

在這種情況下,你想錯了:'我'是一個無記憶的'auto'變量(可以聲明爲'register'),因此在初始化之前讀取它是直的UB。 – Deduplicator 2014-10-10 22:08:36

0

這應該爲你工作!你需要初始化i

#include <stdio.h> 
#include <math.h> 

int main (void) 
{ 
    int i = 0, u = 1000, l =- 1000; 
    float a, b, c, d, mid, y; 

    scanf(" %f %f %f %f", &a, &b, &c, &d); 

    while (abs(u-l)>0.001 && i<10) 
    { 
     mid = (u + l)/2; 
     y = a*pow(mid,3) + b* pow(mid,2) + c*mid + d; 

     if(y == 0) 
      break; 
     else if(y<0) 
      l = mid; 
     else 
      u = mid; 

     i++; 
    } 

    printf("\nThere is a root at: x = %.3f\n", mid); 
} 
0

如果您ul是彩車那麼你的while循環終止,而不i。在此之前,abs(u-l)其中u-lint只有當根位於零時纔會終止。您還需要使用晶圓廠()的ABS,而不是():

int main (void) 
{ 
    float u=1000.0, l=-1000.0; 
    float a, b, c, d, mid, y; 

    scanf(" %f %f %f %f", &a, &b, &c, &d); 

    while (fabs(u - l) > 0.001) 
    { 
    mid= (u + l)/2.0; 
    y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d; 
    if(y == 0) break; 
    else if(y < 0) l = mid; 
    else u = mid; 
    } 
    printf("\nThere is a root at: x = %.3f\n", mid); 
} 

好像你仍然有一些錯誤的二分法算法狀態,當你重新L型和U中旬。我附加了一個固定版本,並且我使用了不同的變量名稱(對不起)來保持我的頭腦清晰:

#define NMAX 1000 
#define TOL 0.00001 
int sign(float x) { 
    if (x > 0.0) return 1; 
    if (x < 0.0) return -1; 
    return 0; 
} 
int main (void) 
{ 
    int n=0; 
    float fa, fc, b=1000.0, a=-1000.0; 
    float p3,p2,p1,p0,c; 

    scanf(" %f %f %f %f", &p3, &p2, &p1, &p0); 

    while(n<NMAX) 
    { 
     c = (a + b)/2.0; 
     fc = p3*pow(c, 3) + p2*pow(c, 2) + p1*c + p0; 

     if(fc == 0.0 || (b-a)/2.0 < TOL) break; 

     fa = p3*pow(a, 3) + p2*pow(a, 2) + p1*a + p0; 
     if(sign(fc) == sign(fa)) 
      a = c; 
     else 
      b = c; 
     n++; 
    } 
    if(n==NMAX) { 
     printf("Method failed.\n"); 
    } 
    else { 
     printf("\nThere is a root at: x = %.3f\n", c); 
    } 
} 
相關問題