2016-09-07 5 views
0

mccaurins 시리즈를 사용하여 arccos (x^2-1)를 계산하지만 math.acos의 결과와 비교할 때 다릅니다.자바를 사용하여 maclaurin 시리즈 arccos 계산에 잘못된 점이 있습니까?

public class Maclaurin { 

    public static int factorial(int fact) { 
     if(fact==0) 
      return 1; 
     return fact*factorial(fact-1); 
    } 

    public static void main(String[] args) { 
    int i, j; 
    double function = 0, x,result; 

    x=0; 

     for (int n = 0; n < 8; n++) { 

      function=((factorial(2*n))/(Math.pow(4, n)*Math.pow(factorial(n),2)*(2*n+1)))*Math.pow((Math.pow(x, 2)-1),2*n+1); 
      result=(Math.PI/2)-function; 

      System.out.println("x= "+x+" y= "+result); 
      System.out.println("Test "+Math.acos(Math.pow(x, 2)-1)); 
      x+=0.13; 
     } 




    } 


    } 

Programm output. test is a value calculated with Math.arccos and it differs from y calculated with mclaurins formula: 

    x= 0.0 y= 2.5707963267948966 
    Test 3.141592653589793 
    x= 0.13 y= 1.7291549939933966 
    Test 2.9574849820283498 
    x= 0.26 y= 1.6236496851024964 
    Test 2.771793621843802 
    x= 0.39 y= 1.5848621264898726 
    Test 2.5828078861333155 
    x= 0.52 y= 1.5725761587226181 
    Test 2.3885331918392687 
    x= 0.65 y= 1.5708496332463704 
    Test 2.1864594293995867 
    x= 0.78 y= 1.570796415168701 
    Test 1.9731661516473589 
    x= 0.91 y= 1.5707963267948972 
    Test 1.7435543826662978 

편집 : 여기 내 코드는 새로운 코드를 계산에 Maclaurin 기능에 있고 내가 메인 함수에서 호출. 첫 번째 3을 제외한 모든 값에 적합 : package maclaurin;

public class Maclaurin { 
    private static double x; 

//public static int factorial(int fact) { 
// if(fact==0) 
//  return 1; 
// return fact*factorial(fact-1); 
//} 
    public static double factorial(int fact) { 
    if(fact==0) 
     return 1; 
    return fact*factorial(fact-1); 
} 

public static void main(String[] args) 
    { 
     x = 0; 
     for (int i=0;i<8;i++) 
      { 
       maclaurin(x); 
       x=x+0.14; 
      } 

    } 

public static void maclaurin(double value){ 
    double function = 0, x, result; 

    x =value; 

    for (int n = 0; n < 20; n++) { 
     function += ((factorial(2 * n))/(Math.pow(4, n) * Math.pow(factorial(n), 2) * (2 * n + 1))) 
       * Math.pow((Math.pow(x, 2) - 1), 2 * n + 1); 
    } 

    result = (Math.PI/2) - function; 
    System.out.println("x= " + x + " y= " + result); 
    System.out.println("Test " + Math.acos(Math.pow(x, 2) - 1)); 
} 




} 
+0

가 다를 않습니다 이상의 값

EDIT3

maclaurin 기능을 감싸 추가? 차이는 볼 수 없습니다. 아마 우리가 당신이 말하는 차이를 볼 수 있다면 우리는 더 잘 도울 수있을 것입니다. – Andreas

+0

@Andreas 여기에 programm 출력이 추가되었습니다. –

+0

@ Andreas 수식을 여러 번 확인했는데 오류를 찾지 못했습니다. –

답변

2

루프에 나타납니다 (16)의 계승, MAX_INT보다 큽니다.

내가 얻을 : 옥타브의

>> factorial(16) 
2.0923e+013 
>> 2^31 
2.1475e+009 

. 범위를 좁히려면 분석 단순화를 수행하거나 int 대신 double을 사용해야합니다.

+0

문제는 있지만 질문에 대답하지 않습니다.그는 작은 입력에 대해서도 잘못된 값을 가지고 있습니다. – JohnnyAW

+0

@Brick은 이것을 확인하지만, JohnnyAW가 이미 작은 값으로도 작동하지 않는다고 말했기 때문에 –

+1

나는이 시리즈가 얼마나 좋은지를 확인하지 못했습니다. 정수의 크기. 그렇지만 @JohnnyAW와 동의합니다. 확장을 시도한 지점까지 "충분히 가깝다"면 시리즈가 올바른 대답으로 수렴 될 것이라고 기대할 수는 없습니다. 얼마나 멀리 갈 수 있는지는 기능의 본질, 보관 한 용어의 수 및 정확성에 달려 있습니다. 당신이 그 부분을 이해하지 못한다면, 다른 곳에서 Maclauren 시리즈에 대해 읽거나 몇 가지 질문을 물어볼 것을 제안합니다. 또한, 매우 큰 계승을 원할 경우, Stirling의 근사법 사용을 고려하십시오. – Brick

2

당신이 이해하지 못하는 것 같아요, 어떤 maclaurin 시리즈 (테일러의 시리즈) 실제로 않습니다. 대략적인 값을 계산할 수 있습니다. n -> ∞에 대해서만 정확한 값을 얻을 수 있습니다. 계산할 수 없기 때문에 몇 가지 n을 정의하고 계산을 중단해야합니다. 실제 값을 얻으려면 합계의 모든 단일 부분을 추가해야합니다. 그래서 기본적으로 당신은 반복 N과 function에 계산 된 값을 추가하고 루프 후에는 result을 계산할 수 있어야합니다

public static void main(String[] args){ 
    double x = 0; 

    for(int i = 0;i < 8;i++){ 
     System.out.println("x: " + x + " maclaurin: " + maclaurin(x)); 
     System.out.println("Test: " + Math.acos(Math.pow(x, 2) - 1)); 

     x += 0.14; 
    } 
} 

public static double maclaurin(double x){ 
    double function = 0; 

    for (int n = 0; n < 10; n++) { 
     function += ((factorial(2 * n))/(Math.pow(4, n) * Math.pow(factorial(n), 2) * (2 * n + 1))) 
       * Math.pow((Math.pow(x, 2) - 1), 2 * n + 1); 
    } 

    return (Math.PI/2) - function; 
} 

내가 꽤 가까운 값을 가지고 이러한 방법 :

x: 0.0 maclaurin: 2.962490972738185 
Test: 3.141592653589793 
x: 0.14 maclaurin: 2.8972172328920296 
Test: 2.9432779368601296 
x: 0.28 maclaurin: 2.7366715068800485 
Test: 2.7429790581451043 
x: 0.42000000000000004 maclaurin: 2.5381695201901326 
Test: 2.5385256934250617 
x: 0.56 maclaurin: 2.3273181153351756 
Test: 2.327323409412957 
x: 0.7000000000000001 maclaurin: 2.105981109221438 
Test: 2.1059811170704963 
x: 0.8400000000000001 maclaurin: 1.8696239609917407 
Test: 1.8696239609918046 
x: 0.9800000000000001 maclaurin: 1.6104066839613247 
Test: 1.6104066839613247 

보인다, 즉 결과를 좋은 결과를 얻으려면 n을 늘릴 수 있지만 어느 시점에서는 factorial이 오버플로하기 때문에 어느 시점에 NaN이됩니다.

이 @Brick 같은 factorial을 변경하는 것을 잊지 마세요 제안 :

public static double factorial(int fact) { 
    if(fact==0) 
     return 1; 
    return fact*factorial(fact-1); 
} 

당신이 반복적 인 방법으로 factorial을 계산하는 방법을 궁금해하는 경우, 여기에 예입니다 (실제로이 특정한 경우에 문제가되지 않습니다 하지만 헤이, 우리는 바로, 새로운 것을 배우고 현재) :

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

편집 : int

,536,913,632에 fact 매개 변수를 변경 10

EDIT2는 : 반복 첨가 factorial

+0

아마 인자를'factorial()'으로'int'로 바꿔야하지만, 반환 값은'double'으로 유지해야합니다. – Andreas

+0

@Andreas 예,'fact == 0'은 그렇지 않으면 "더티"가되지 않을 것입니다. :) – JohnnyAW

+0

질문에 대한 답을 알고 있습니다 만,'factorial()'은 순환이되어야 재귀가 아닙니다. 아마도 문제가 될만큼 높은 값으로 호출하지 않을 것이지만 재귀는 'StackOverflowError'를 유발할 수 있습니다. 게다가 루핑은 재귀보다 빠릅니다. – Andreas