2017-08-25 95 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