Kamil Szmit Napisano Marzec 10, 2009 Zgłoś Share Napisano Marzec 10, 2009 Zrobiłem program do obliczania sinh za pomocą szeregu z określoną dokładnością i wyliczający błąd względny ze wzoru (wartość obliczona z szeregu - wartość obliczona za pomocą sinh)/wartość obliczona za pomocą sinh: #include <stdio.h> /*printf, scanf, fgets, putchar*/ #include <math.h> /*sinh*/ int main(void) { printf("\nProgram oblicza z zadaną dokładnością wartość sinh i wartość błędu względnego w stosunku do wartości uzyskanej przy pomocy standartowej funkcji języka C"); while(1) /*pętla nieskończona*/ { double y = 0, /*wynik funkcji obliczonej za pomocą szeregu*/ error, /*stokrotność błędu względnego*/ x, /*argument funkcji*/ z; /*wynik funkcji obliczonej za pomocą funkcji bibliotecznej*/ unsigned int n, /*dokładność*/ k; /*zmienna oznaczająca dany element szeregu*/ char other[2]; /*znak po cyfrze*/ printf("\n\nPodaj wartość, dla której ma być obliczony sinh (inny znak niż cyfra i \".\" zamyka program): "); /*napisz co trzeba podać*/ if (scanf("%lf",&x) == 0) /*pobierz liczbę, a jeśli jej nie ma, to zamknij program*/ { putchar('\n'); /*pozostaw pusty wiersz po programie*/ return 0; } fgets(other, 2, stdin); /*pobierz znak po cyfrze*/ if (other[0] != '\n') /*jeśli to nie jest znak nowego wiersza, zamknij program*/ { putchar('\n'); /*pozostaw pusty wiersz po programie*/ return 0; } printf("Podaj dokładność (0 i inny znak niż cyfra zamyka program): "); /*napisz co trzeba podać*/ if (scanf("%u",&n) == 0 || n == 0) /*pobierz liczbę, a jeśli jej nie ma lub jest nią 0, to zamknij program*/ { putchar('\n'); /*pozostaw pusty wiersz po programie*/ return 0; } fgets(other, 2, stdin); /*pobierz znak po cyfrze*/ if (other[0] != '\n') /*jeśli to nie jest znak nowego wiersza, zamknij program*/ { putchar('\n'); /*pozostaw pusty wiersz po programie*/ return 0; } for (k=1; k<=n; k++) /*obliczanie szeregu*/ { unsigned long a; /*zmienna do przechowywania wykładnika potęgi, a potem będąca mianownikiem w elemencie szeregu*/ unsigned int c; /*pomocnicza zmienna do pętli, najpierw oznaczająca dany stopień przy liczeniu potęgi, a potem liczbę o 1 mniejszą przy liczeniu silni*/ double b; /*licznik w elemencie szeregu*/ a = 2*k-1; /*zapamiętanie wykładnika potęgi w danym elemencie szeregu*/ b = x; /*przypisanie do licznika argumentu funkcji*/ for(c=1; c<a; c++) /*liczenie potęgi, wzrastanie zmiennej pomocniczej do wykładnika potęgi*/ { b = b * x; /*mnożenie licznika przez argument funkcji*/ } for(--c; c>=2; c--) /*zamiana wykładnika potęgi na jego silnie wykonywanie aż zmienna pomocnicza zmniejszy się do 1*/ { a = a * c; /*mnożenie przez liczbę o 1 mniejszą*/ } y = y + (b/a); /*dodaj element szeregu do wartości funkcji*/ } printf("sinh(%.16f) = %.16f\n", x, y); /*wyświetl sinh obliczony za pomocą szeregu*/ z = sinh(x); /*oblicz wartość sinh za pomocą funkcji bibliotecznej*/ error = ((y - z)/z)*100; /*oblicz stokrotność błędu względnego*/ printf("Błąd względny: %.16f", error); /*wyświetl błąd względny*/ putchar('%'); /*pokaż znak procent*/ } } Działa bez problemu mniej więcej dla dokładności n<17 oraz argumentu -60<x<-66. Dla większych argumentów zwraca -100% jako błąd względny, dla mniejszych -NaN, a dla większych dokładności Infinity jako wartość funkcji obliczona z szeregu i jako błąd względny. Dlaczego? Program dobrze liczy potęgę i silnie. Czy -100% i -NaN oznacza liczbę mniejszą od -99,9999999999999999 a większą od -100. Czy ktoś umiałby dokładnie oszacować liczby, dla których program poprawnie liczy? Kompiluje w systemach OpenSolaris 2008.11 i Solaris 9 za pomocą gcc -ansi -pedantic -Wall -lm. GCC nie pozwolił mi użyć "%lf" w funkcji "printf". Czy dobrze, że użyłem "%.16"? Wyliczyłem te 16 wpisując do double liczby, a następnie wyświetlając jest licząc ile cyfr po przecinku zostało poprawnie wyświetlonych. Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Marzec 10, 2009 Zgłoś Share Napisano Marzec 10, 2009 nie wychodzisz moze poza otoczenie punktu ? Nie pamietam juz dokladnie ale z tych okruchow co mi zostaly pamietam ze dokladnosc jest zalezna od przedzialu z jakiego sa brane arg. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.