Forum Programowanie c++, delphi Ostatnio aktywny: Nigdy
Nie zalogowany [Zaloguj ]
Pokaż koniec
Wersja do druku | Zapisz | Dodaj do Ulubionych   Wyślij nową wiadomość Sonda:
Autor: Temat: [C] Obliczanie sinh za pomocą szeregu
szmitek
Newbie
*




Postów: 4
Zarejestrowano: 28-1-2009
Miasto: Chotomów
Offline


sad.gif wysłano w 10-3-2009 o godz. 18:44 Odpowiedz cytując
[C] Obliczanie sinh za pomocą szeregu



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:


Kod:
#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("nnPodaj 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) = %.16fn", 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.




Pokaż profil użytkownika Pokaż wszystkie wiadomości użytkownika Użytkownik U2U
Michael
Junior Member
*




Postów: 17
Zarejestrowano: 14-2-2006
Offline

Nastrój: Brak

[*] wysłano w 11-10-2009 o godz. 19:39 Odpowiedz cytując


Nie czytałem kodu (formatowanie zniechęca wystarczająco) ale z opisu problemu wydaje mi się że powinieneś zainteresować się bibliotekami liczb wysokiej precyzji np. GNU MP.



Pokaż profil użytkownika Pokaż wszystkie wiadomości użytkownika Użytkownik U2U Ten użytkownik posiada komunikator Gadu-Gadu
Wyślij nową wiadomość Sonda:


Pokaż początek

Sitemap
Copyright © 2005-2007 by coding-portal.com
Programowaniedla każdego. Programowanie w c++, java, delphi, pascal, perl oraz innych językach. Tworzenie stron w html, xhtml, php z użyciem mysql, css oraz ich pozycjonowanie. Zapraszamy do udziału w życiu naszego forum!
[zapytań: 15]
[PHP: 85.0% - SQL: 15.0%]