robek210 Temat założony przez niniejszego użytkownika |
[C] cosinus rozwijany w szereg Maclaurina » 2013-11-13 15:27:27 Witam wszystkich, Na samym początku zaznaczę, że dopiero uczę się programować. Otóż próbuję napisać program w C wyznaczający wartość funkcji trygonometrycznych cos z rozwinięcia w szereg Maclaurina - wzór: http://tiny.pl/qtldsDane wejściowe: 1. xp - dolna granica zmiennej x 2. xk - górna granica zmiennej x 3. krok - z jakim następuje powiększanie x 4. dokładność obliczeń w procentach - ograniczająca liczbę wyrazów szeregu potęgowego Po dość długim kombinowaniu udało mi się stworzyć poniższy kod ale nie mam pojęcia jak wstawić dokładność. Dodatkowo dla wartości x=>42 program wypisuje nierealne wartości cosinusa co może ma coś wspólnego właśnie z brakiem tej dokładności... Byłbym bardzo wdzięczny gdyby ktoś znalazł chwilę i pomógł Program pisany za pomocą CodeBlocks'a #include<stdio.h> #include<math.h> int main() { float xp, xk, krok; int z; printf( "Podaj poczatkowa liczbe xp:\n" ); scanf( "%f", & xp ); printf( "Podaj koncowa liczbe xk:\n" ); scanf( "%f", & xk ); printf( "Podaj krok z jakim ma nastepowac powiekszenie x:\n" ); scanf( "%f", & krok ); z =( xk - xp ) / krok; double cos1, wyr, x, lp; x = 0; int i, j, n; printf( "Wartosc x: \t" "Wartosc cosx:\n" ); for( x = xp, j = 0; j <= z; ++j ) { lp = x; cos1 = 1; wyr = 1; for( i = 2; i <= n; ++i ) { wyr = wyr *((( - 1 ) * x * x ) /(( 2 * i - 3 ) *( 2 * i - 2 ) ) ); cos1 = cos1 + wyr; } printf( "%5.2lf %5.2lf \n", lp, cos1 ); x = lp + krok; } return 0; }
|
|
docentpp |
» 2013-11-13 16:23:55 We wzorze McLaurina dokładność obliczeń zależy od ilości zsumowanych wyrazów. Zależy więc od n , a nie od xp,xk.............
Przynajmniej ja tak interpretuję ten wzór. :-) |
|
robek210 Temat założony przez niniejszego użytkownika |
» 2013-11-13 16:37:56 Też tak mi się wydaje i właśnie tu jest problem. Nie wiem w jaki sposób na podstawie wprowadzonej dokładności ograniczyć liczbę wyrazów szeregu... |
|
docentpp |
» 2013-11-13 17:19:45 To jest ciąg szybko zbieżny,więc np. eps=dokładność , można porównywać z kolejno wyliczanymi elementami szeregu, i jeśli kolejny wyraz jest mniejszy niż eps, to osiągnie się zakładaną dokładność.
|
|
robek210 Temat założony przez niniejszego użytkownika |
» 2013-11-13 18:00:04 Chyba nie do końca o to chodzi ... for( i = 2; i <= n; ++i )
{ wyr = wyr *((( - 1 ) * x * x ) /(( 2 * i - 3 ) *( 2 * i - 2 ) ) ); cos1 = cos1 + wyr; }
if( cos1 <= epsilon ) { printf( "%5.2lf %5.2lf \n", lp, cos1 ); } x = lp + krok;
} return 0; }
Jak próbowałem porównywać z "wyr" to wychodziły strasznie kosmiczne wyniki, a tu po prostu sprawdza czy dana wartść cosinusa jest mniejsza od podanego ułamka ( zrobiłem epsilon=epsilon/100 żeby zamienić procenty na ułamki) |
|
docentpp |
» 2013-11-13 19:01:55 Najłatwiej będzie znaleźć błąd jeśli przeredagujesz swój kod do pojedynczej funkcji,do postaci wyliczającej cosinus wg McLaurina z określoną ilością wyrazów,bez rozpatrywania dokładności. Czyli : double cosinusMcL( double x, int k ) { }
Potem wstaw do wywołania funkcji np x=0.23 , k=30 ; np x=0.23 , k=50 ; i porównaj z wartościami tabelarycznymi, co da odpowiedź,czy twój algorytm i kod są prawidłowe. Powtarzam, ciąg jest mocno zbieżny....... |
|
docentpp |
» 2013-11-14 00:36:30 Napisałem takie rozwiązanie : float cosinus( float x, int n ) { float l, d, xx, wyr; l = 1.0; d = 1.0; xx =- x * x; wyr = 1.0; for( int i = 2; i <= n; ++i ) { l *= xx; d *= 1.0 *( 2 * i - 3 ) *( 2 * i - 2 ); wyr = wyr +( l / d ); } return wyr; }
Przetestowałem dla różnych x,n. Już dla n=6 wyniki są porównywalne ze standardowym cosinusem z biblioteki <math.h> // float sin(float x) Uzywam Dev 4.9. Dokładność obliczeń eps należy porównywać z wartością bezwzględną kolejnego wyrazu ciągu McLaurina. |
|
robek210 Temat założony przez niniejszego użytkownika |
» 2013-11-14 10:41:17 Zmodyfikowałem Twój kod (nie wiem oczywiście czy w dobry sposób) na potrzebę zadania i program nie wypisuje kompletnie nic... #include<stdio.h> #include<math.h> int main( void ) { float xp, xk, krok, epsilon, x; int z, j; printf( "Podaj poczatkowa liczbe xp:\n" ); scanf( "%f", & xp ); printf( "Podaj koncowa liczbe xk:\n" ); scanf( "%f", & xk ); printf( "Podaj krok z jakim ma nastepowac powiekszenie x:\n" ); scanf( "%f", & krok ); printf( "Podaj dokladnosc w procentach ograniczajaca liczbe wyrazow szeregu:\n" ); scanf( "%f", & epsilon ); epsilon = epsilon / 100; z =( xk - xp ) / krok; float cosinus( float x, int n ) { float l, d, xx, wyr; l = 1.0; d = 1.0; xx =- x * x; wyr = 1.0; int i; x = xp; for( j = 0; j <= z; ++j ) { for( fabs( wyr ) <= epsilon, i = 2; i <= n; ++i ) { l *= xx; d *= 1.0 *( 2 * i - 3 ) *( 2 * i - 2 ); wyr = wyr +( l / d ); } printf( "%5.2lf %5.2lf \n", x, wyr ); x = x + krok; } } return 0; }
|
|
« 1 » 2 |