2015-11-02 60 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