2013-09-21 89 views
0

我在C++中應用Regula Falsi方法,但問題是當F(x3)變爲0時使用==運算符,然後if(fabs(f(x3))== 0應該停止並且從環路出來,但它不會停止爲什麼爲什麼爲什麼.... 像12日迭代F(X3)= 0,但如果(晶圓廠(F(X3)== 0))後,下方輸出不運行。循環不停止它不應該去第13次迭代C++ ==操作符不工作

float f(float x) 
{ 

float f_x; 
f_x= pow(x,3)+(3*x)-5; 
return f_x; 
} 
int main(int argc, char** argv) 
{ 

float a,b,tol,x3; 

int itr,n; 

cout << "enter the iterations"; 
cin >> itr; 
cout << "enter the interval a"; 
cin >> a; 
cout <<"enter the interval b"; 
cin >> b; 
cout << "enter the toleration"; 
cin >> tol; 

cout.setf(std::ios_base::fixed, std::ios_base::floatfield); 
cout.precision(5); 

//cout<<"fa="<<f(a)<<"fb"<<f(b); 
cout<<"n\t\ta\t\tb\t\tx3\t\tf(a)\t\tf(b)\t\tf(x3)" <<endl; 
if (f(a)*f(b)<0 && a<b) 
{ 
    for (n=0;n<itr;n++) 
    { 
     x3=a-((b-a)*f(a))/(f(b)-f(a)); 
     cout << "xx"<<fabs(f(x3)); 

     if (fabs(f(x3))==0) 
     { 
      cout << "Solution"<<fabs(f(x3)); 
       break; 
     } 
     else 
     { 
      cout<<n+1 <<"\t\t"<<a <<"\t\t"<<b <<"\t\t"<<x3<<"\t\t"<<f(a) 
      <<"\t"<<f(b)<<"\t\t"<<f(x3) <<endl; 
      if(f(x3)*f(a)<0) 
        b=x3; 
       else 
        if(f(x3)*f(b)<0) 
        a=x3; 
     } 
    } 
} 
else 
    cout<< "No Solution Exist"; 

return 0; 

}

輸出

在大多數情況下,進入iterations13

進入區間A1

進入區間B2

進入toleration1

**n a   b    x3   f(a)   f(b)   f(x3)** 


1 1.00000 2.00000  1.10000  -1.00000  9.00000  -0.36900 

2 1.10000 2.00000  1.13545  -0.36900  9.00000  -0.12980 

3 1.13545 2.00000  1.14774  -0.12980  9.00000  -0.04487 

4 1.14774 2.00000  1.15197  -0.04487  9.00000  -0.01542 

5 1.15197 2.00000  1.15342  -0.01542  9.00000  -0.00529 

6 1.15342 2.00000  1.15391  -0.00529  9.00000  -0.00181 

7 1.15391 2.00000  1.15408  -0.00181  9.00000  -0.00062 

8 1.15408 2.00000  1.15414  -0.00062  9.00000  -0.00021 

9 1.15414 2.00000  1.15416  -0.00021  9.00000  -0.00007 

10 1.15416 2.00000   1.15417 -0.00007  9.00000  -0.00003 

11 1.15417 2.00000   1.15417 -0.00003  9.00000  -0.00001 

12 1.15417 2.00000   1.15417 -0.00001  9.00000  0.00000 

13 1.15417 2.00000   1.15417 -0.00000  9.00000  0.00000 
+0

它可能是一個非常小的值,但不爲零(並且您在打印時不會看到它) - 您可以嘗試將條件從「== 0」更改爲「 Leeor

+0

這是可怕的代碼。浮點數等於另一個的條件幾乎無法通過計算來滿足。 **不要那樣做**。 – Walter

回答

1

這裏的問題是不是浮點精度;這是你願意接受你的結果的寬容。在大多數情況下,regula falsi會讓你越來越接近正確的結果,因爲你運行更多的迭代,但它會而不是給你確切的答案。所以你必須做出的決定是,你希望結果有多接近?這是現實世界對準確性要求和獲得結果所需時間之間的折衷;更高的精度需要更多的計算時間因此,請選擇適合您的任務的容差,然後重複該循環,直到結果在容差範圍內。如果結果太慢,則必須增加容差。

+0

你是絕對正確的,我剛剛把0.1,它停止感謝你這麼多 – Artemis

3

浮點運算具有精度誤差,所以更好爲了不直接比較浮點值,請使用epsilon

bool float_equal(float a , float b) 
{ 
    return std::abs(a-b) < 0.001; 
} 

注意,在你的情況(與零比較)的精確度,更重要的:浮點實現被dessigned提供圍繞零更高的精度。因此,例如,您可以使用0,000000000001或0,0000000000000000001這些不被認爲等於零的數字。

檢查這個線程更多的考慮:What is the most effective way for float and double comparison?

此外,注意std::setprecision是改變輸出(打印)操作的精度,而不是浮點「系統」的精確的操縱。

+1

恩,在這裏使用誤差範圍是適當的,因爲循環在理論上通常不會產生完全零,即使是無限次的迭代。這不**意味着比較應該總是使用一個範圍。這是一種先進的技術,具有明顯的缺點;特別是'float_equal(x,y)'爲真,'float_equal(y,z)'爲真**不會**暗示'float_equal(x,y)'爲真。 –

+0

@PeteBecker是因爲這種情況下(x vs y vs z)我已經包含一個鏈接到一個線程,談論這個。 (特別是[這個答案](http://stackoverflow.com/a/77735/1609356)) – Manu343726

+1

是的,該鏈接說明你的斷言「從不直接比較浮點值」是錯誤的。 –

1

你確定f(x3)正好是0,而不是 - 說 - 0.0000000001?

浮點數可以非常準確地在0附近,有時甚至可以在點後小到45位。

+0

我正在使用cout << fabs(f(x3))它只給出了0,而且我也將cout.precesion(5)設置爲5個十進制 – Artemis

+3

這就是要點。如果將打印精度設置爲5,則當實際值爲0.000001(及以下)時,您將看到0。 cout.precision只設置打印精度,而不是計算精度。 – CygnusX1

+0

非常感謝你0.000001032值後十三迭代不爲零哇你只是搖滾 – Artemis