2015-11-02 53 views
2

我試圖計算辛普森的規則來得到準確性爲< 10^-6。但是每當函數運行時,由於0/sin(0),我得到一個NaN或DNE錯誤。當I = 1時,如何解決這個錯誤? **我的編輯功能,包括當我== 1計算辛普森規則錯誤<10^-6

public static double simpsonsRuleFunction1(double valueN, double valueA, double valueB, double valueDx) { 

    double e = 0.0; 
    double simpsonsRule = 0.0; 
    double valueHolder = 0.0; 

    valueN = 2; 
    valueA = 0; 
    valueB = (Math.PI)/2; 

    for(int i = 1; i<=valueN+1 ; i++){ 
     valueDx = (valueB-valueA)/valueN; 
     e = valueA + ((i-1)*valueDx); 

     if (i==1) { 
     // Limit as x -> 0 
     simpsonsRule += Math.pow(10,-10); 

     } 
     else if ((i % 2 == 0) && (i > 1) && (i < valueN+1)) { 
     simpsonsRule += 4*(e/((Math.sin(e)))); 
     } 
     else if ((i % 2 != 0) && (i > 1) && (i < valueN+1)) { 
     simpsonsRule += 2*(e/((Math.sin(e)))); 
     } 
     else if (i == valueN+1) { 
      simpsonsRule += (e/((Math.sin(e)))); 

     } 

    } 
    simpsonsRule = simpsonsRule *((valueDx)/3); 



    while(Math.abs(valueHolder - simpsonsRule) > Math.pow(10,-6)) { 
      System.out.println("\nValueHolder" + valueHolder); 
      valueHolder = simpsonsRule; 
      valueN +=2; 
      valueDx = (valueB-valueA)/valueN; 
      simpsonsRule = 0; 
    for(int i = 1; i<=valueN + 1; i++){ 
     e = valueA + ((i-1)*valueDx); 

     if (i==1) { 
     // Limit as x -> 0 
     simpsonsRule += Math.pow(10,-10); 

     } 
     else if (i % 2 == 0) { 
     simpsonsRule += 4*(e/((Math.sin(e)))); 
     } 
     else if ((i % 2 != 0) && (i > 1) && (i < valueN + 1)) { 
     simpsonsRule += 2*(e/((Math.sin(e)))); 
     } 
     else if (i == valueN + 1) { 
      simpsonsRule += (e/((Math.sin(e)))); 

     } 

    } 
    simpsonsRule = simpsonsRule *((valueDx)/3); 


    } 
    return valueN; 
} 
+0

我需要N個錯誤<10^-6的區間。 –

+0

N只是正數,偶數 –

回答

2

您將需要處理的情況下e==0明確。

我建議你拉出一個功能,讓您不必再重複的邏輯:

double f(e) { 
    return e==0 ? 1 : e/Math.sin(e); 
} 

,然後只用這無論你需要計算功能,例如

simpsonsRule += 4*(e/((Math.sin(e)))); 

變爲

simpsonsRule += 4*f(e); 

,當然,你也可能需要在+/- N pi處理的情況下,根據輸入值您允許。

針對pcarter的建議進行編輯:您可能希望使用低於該閾值的非零閾值,使用1作爲函數的值,以處理零周圍的數字不準確性。

return (Math.abs(e) < 1e-10) ? 1 : e/Math.sin(e); 

其中選擇所述閾值(在這種情況下1e-10),得到足夠精確的結果。

+0

因此,無論何時e == 0,我會使用限制作爲x - > 0我的函數,x/sinx?確切地說, –

+0

。這是1來自哪裏。 –

+3

由於四捨五入問題,您需要仔細比較浮點值與'=='。使用'Math.abs(e)<1.0e-10'代替'e == 0'會更好(在這裏'1.0e-10'是相當隨意的。) – pcarter