2013-02-14 236 views
0

我正在寫一個二分法算法來找到多項式的根。我的代碼的第二部分說,如果FP等於零或絕對值b-a它只是打破了我猜的if語句。如何擺脫循環c

我希望程序完全停止for循環(迭代)並返回p。最後,我想打印獲得解決方案所需的迭代次數,但顯然使用我的printf語句,它顯示程序仍然執行,即使認爲獲得了根(零)。

任何關於如何停止整個機制的想法,並返回p的值爲零和確切的迭代次數?由於

double computeroots(double a, double b, double epsilon, int MaxIter) 
{ 
    double FA = pow(a,4) -4*a + 1; 
    double FB = pow(b,4) - 4*b + 1; 
    double FP; 
    double p; 
    int i; 

    for(i=0;i<MaxIter;i++) { 
     if(FA * FB < 0) { 
      p = a + (b-a)/2; 
      FP = pow(p,4) - 4*p +1; 
      if(FP == 0 || abs(b-a) < epsilon) { 
       return p; 
       break; 
      } else if (FA * FP >0) { 
       a =p; 
       FA = FP; 
      } else { 
       b = p; 
       FB = FP; 
      } 
      i++; 
     } 
    } 

    printf("the number of iterations is : %d\n", i); 
} 
+1

我沒有改變你的標題第二遞增,但它絕對是誤導性的。你只有一個循環,而不是外部循環和嵌套循環。 – 2013-02-14 15:15:57

+0

你正在增加'i'兩次,所以你只運行一半的迭代。 – 2013-02-14 15:16:36

回答

3

printf語句不打,因爲你有break語句前return p;。 A return語句立即退出該功能。

您需要printf後到return聲明移到或移動printfreturn

 if(FP == 0 || abs(b-a) < epsilon) 
     { 
      printf("the number of iterations is : %d\n", i); 
      return p; 
     } 
     ... 

    printf("failed to converge after %d iterations\n", i); 
    return p; 
} 
+2

或者離開休息時間並將'return'移動到函數的末尾(它屬於!) – 2013-02-14 15:26:47

0

您可以返回雙打,其中第一個元素是結果的數組,而第二一個是迭代次數。

或者,您通過引用變量的函數,並分配給它,就像這樣:

double compute_something(int param1, int param2, int* iterations) { 
    // your code ... 
    // when you want to return, use this: 
    *iterations = 5; 
    return 1.23; 
    // your code ... 
} 

int iter; 
double result = compute_something(1,2, &iter); 

在此之後,結果中包含的結果,ITER你存儲的迭代次數。 該解決方案可能會更好,因爲您沒有將迭代次數(顯然是整數)返回爲double。

1

如果您有return聲明,那麼您的break聲明是無用的。返回值退出函數的範圍並返回給調用者,以便以後不再執行任何指令。

所以這個:

return p; 
break; 

應該變成:

printf("the number of iterations is : %d\n", i); 
return p; 

如果你看到退出條件選擇不正確我猜想它更是一個有限精度問題。您正在檢查​​,但FPdouble,所以您必須在FP足夠接近0時停止,而不是當它完全相等時停止。例如:abs(FP) < epsilon

0

當你需要返回多個值時,你可以用out-arguments來完成。你的函數改爲

double computeroots(double a, double b, double epsilon, int MaxIter, int *numIterations) 

調用它像這樣:

int numIter; 
soln = computeroots(a, b, epsilon, MaxIter, &numIter); 

,並在你的函數,只是返回之前,添加:

*numIterations = i; 
+0

謝謝阿德里安你保存了這一天..但是我不明白的是你說的是computeroots應該期望一個指向numIterations的整數的指針吧!到目前爲止這麼好,當你調用它時,你使用&符號,這也是好的,因爲它是一個指針..但是令人困惑的是你聲明numIterations是一個整數而不是指向整數的指針..哪些工作很好,但我仍然感到困惑,我們應該聲明int * numIterations主要不只是int numIterations – user2059456 2013-02-16 17:35:29

+0

當我想在printf中顯示numIterations的值時,它返回一個不兼容的警告。我說printf(「.....」,* numIterations);這是錯誤的我知道不應該有一個星號,但我不明白爲什麼。由於它是一個指針,它應該在它之前得到星號以便返回它指向的值。沒有星號,它應該返回它指向的變量的地址而不是值...任何說明請 – user2059456 2013-02-16 17:39:20

+0

這不是一個指針。這是一個正常的整數購買,你通過引用該函數傳遞它:&可以被翻譯爲「內存方向...」。所以在你使用的函數*(這是間接運算符,你可能會覺得有用的翻譯爲「內存方向的內容...」)。 你可以使用正常變量的內存引用,它們不一定必須是指針。 – 2013-02-16 17:46:20

0

要合併所有必要的mods/S:

double computeroots(
    double a, 
    double b, 
    double epsilon, 
    size_t MaxIter, 
    size_t * pNumIter 
) 
{ 
    double FA = pow(a,4) -4*a + 1; 
    double FB = pow(b,4) - 4*b + 1; 
    double FP; 
    double p = NaN; 
    size_t i; 

    for(i=0; i<MaxIter; ++i) { 
     if(FA * FB < 0) { 
      p = a + (b-a)/2; 
      FP = pow(p,4) - 4*p +1; 
      if(FP == 0 || abs(b-a) < epsilon) { 
       break; 
      } else if (FA * FP >0) { 
       a =p; 
       FA = FP; 
      } else { 
       b = p; 
       FB = FP; 
      } 
     } 
    } 

    *pNumIter = i; 

    printf("the number of iterations is : %z\n", *pNumIter); 

    return p; 
} 

這樣調用它:上模/ s的

double a, b, epsilon; 
size_t sizeMax, sizeIterations; 

... /* some initialisations here */ 

double d = computeroots(a, b, epsilon, sizeMax, &sizeIterations); 

注:

  • 除去錯位的return
  • 加入缺少在端返回
  • 改變int s至是size_t,作爲unsigned型西服計數器
  • 更好
  • 添加引用addtionaly size_t變量返回迭代次數
  • 刪除的i