2017-08-25 122 views
1

我試圖用泰勒近似來評估1.89的sin的近似值。我將輸出與Math.sin(x)的值進行了比較;然而,在大約14個術語之後,我的價值偏離很大並且變得錯誤。我嘗試了x的較小值(< 0.5)的近似值,並且這些值相匹配。使用20項計算sin(x)的近似值

我只是想弄清楚爲什麼在Mac OSx上使用崇高和通過bash編譯的Java偏離了真正的輸出。

public class Test { 

    public static void main (String[] args) { 
     double x = 1.89; 
     double sinx = 0; 
     int n = 20; 
     int countOdd = 1; 
     int counter = 1; 
     int result = 0; 
     int value = 0; 

     while (countOdd <= n) { 
      if (counter%2 != 0) { 
      // Even term odd number 
       if (countOdd%2 == 0) { 
        sinx = sinx - (Math.pow(x,counter)/(double)factorial(counter)); 
        System.out.println(" counter even odd term = " + countOdd); 
        countOdd++; 
        System.out.println(" sinx = " + sinx); 
       } 
       // Odd term odd number 
       else { 
        sinx = sinx + (Math.pow(x,counter)/(double)factorial(counter)); 
        System.out.println(" counter odd odd term = " + countOdd); 
        countOdd++; 
        System.out.println(" sinx = " + sinx); 
       } 
      } 
      // Update the result and reset the value 
      //sinx = sinx + value; 
      //value = 0; 
      System.out.println(" counter = " + counter); 
      counter++; 
     } 

     System.out.println(" sinx = " + sinx); 
     System.out.println(" sinx from math library = " + Math.sin(x)); 
    } 

    /** calcutes and returns n! 
    @param n : a positive integer number 
    @return n! 
    */ 
    public static int factorial(int n) 
    { 
     // your code goes here 
     int result = 1; // if n = 0, while loop is by passed and 0 is returned 
     while (n >= 1) { 
      result = result * (n); 
      n--; 
     } 

     return result; 
    } 
} 
+2

嘗試打印出''n'的'factorial'函數的結果。 –

+0

@AndyTurner,感謝您的建議,我將運行一個循環,並比較以查看函數是否按預期工作,我嘗試了單點值並在初始停止 – Diante

回答

1

的原因是在這裏:

public static int factorial(int n) { 
    int result = 1; 
    while (n >= 1) { 
     result = result * (n); 
     n--; 
    } 
    return result; 
} 

你是不是在考慮到階乘收斂速度非常快產生溢出(有些結果是那麼負數)

可以驗證BEH 。拆分一點在使用階乘返回值的代碼:

while (countOdd <= n) { 

     if (counter % 2 != 0) { 
      // Even term odd number 
      if (countOdd % 2 == 0) { 
       int factorial = factorial(counter); 
       System.out.println("factorial: " + factorial); 
       sinx = sinx - (Math.pow(x, counter)/factorial); 
       System.out.println(" counter even odd term = " + countOdd); 
       countOdd++; 
       System.out.println(" sinx = " + sinx); 
      } 
      // Odd term odd number 
      else { 
       int factorial = factorial(counter); 
       System.out.println("factorial: " + factorial); 
       sinx = sinx + (Math.pow(x, counter)/factorial); 
       System.out.println(" counter odd odd term = " + countOdd); 
       countOdd++; 
       System.out.println(" sinx = " + sinx); 
      } 
     } 

,你會注意到,輸出會產生被distroying你想要達到的數值逼近負值

... 
counter even odd term = 10 
sinx = 0.9476740866450655 
counter = 19 
counter = 20 
factorial: -1195114496 
+0

非常感謝,將該類型更改爲double,並且值無效溢出!將在5分鐘內標記爲解決方案,並表示感謝。 – Diante

+1

仍然考慮factorial從不產生小數的事實,所以不需要double。 –

+0

公平點,我只是刷新了我對基本數據類型的記憶,並選擇了long。再次感謝! – Diante

2

建議使用BigDecimal而不是doubleint進行大數值計算,如階乘和功率。

+0

感謝您的支持,我對BigDecimal類型不熟悉。 – Diante