2017-01-21 18 views
-1

나는 쉽게 작업하고있다. 나는 추측한다. 그러나 나를 괴롭히는 뭔가가있다.Cosine Taylor aproximation C 언어

double x,t,cos_aprox,eps; 
int k; 
t=1.0; 
k=1; 
cos_aprox=1.0;` 

printf("Introduceti x pentru care se calculeaza cos(x) si eroarea epsilon:\n"); 
if(scanf("%lf%lf",&x,&eps)!=2) 
{ 
    printf("Date eronate!!\n"); 
    exit(1); 
} 
else 
{ 
    do 
    { 
     t=t*(-1)*x*x/(k*(k+1)); 
     cos_aprox+=t; 
     k+=2; 

    } 
    while(fabs(t)>eps); 

    printf("Valoarea aproximativa a lui cos(%g) este %.9g. k este %d\n",x,cos_aprox,k); 
    printf("Valoarea lui cos(%g), folosind functia din biblioteca, este %.9g.",x,cos(x)); 
} 

그것은 좋은 결과를 반환하지만 39 라디안 이상의 값을 선택할 때와 라이브러리 함수 cos(x) 사이에 상당한 차이가있다.

추측 하시겠습니까?

+2

인수가'[-pi/4, pi/4]'범위에있는 경우에만 작동합니다. 축소에 필요한 pi의 자릿수에 대해 큰 정수 수학이 필요합니다. 논문 : http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.67.5616 – deamentiaemundi

+0

개선을 위해 while 루프 앞에'x = fmod (x, 2 * pi);를 사용하십시오. 이것은 여전히'x> 1e10'과 같이 큰'x'에 문제가 있습니다. 자신의 코드를 사용하여'cos()'를 광범위하게 사용하는 방법에 대한 세부 사항은 "쉬운 것"이 아닙니다. – chux

답변

1

OP의 Taylor 's 시리즈 사용은 증가하는 값이 x 인 경우 수치 제한이 있습니다. 큰 교대 사인 항이 추가되면 너무 많은 오류가 누적됩니다. 이 조항을 보려면 코드를 수정하십시오. [-2π ... + 2π]의 범위에서 인수 감소와

t = t*(-1)*x*x/(k*(k+1)); 
printf("%e\n", t); 

모두 사인 및 코사인 계산 이득. 다음은 좋은 첫 번째 단계이며 넓은 범위의 x에 대한 오류를 줄입니다.

x = fmod(x, 2*π); 

범위로 추가 감소 [0 ... + π/4] 통상의 삼각 함수와 remquo()를 사용하여 사용될 수있다. Degrees example


문제는 상기 계산 π의 근사값에 의존한다는 것이다. 비합리적 인 수인 π는 정확하게 double으로 나타낼 수 없습니다. 모든 유한 double은 유리수입니다. 대신 기계 파이이 사용됩니다. double x 정교한 확장 정밀 기술을 필요로


// example 
#define M_PI 3.1415926535897932384626433832795 
x = fmod(x, M_PI); 

전체 범위에 걸쳐 정확한 계산을 달성했다. 큰 인수에 대한 인수 감소 : 마지막 비트까지 양호