sinh(x) z szeregu Taylora - nie dziala dla duzych zmiennych

0

Czesc, mam taki problem: napisalem program liczacy sinh(x) z rozwiniecia w szereg Taylora, ale nie dziala dla duzych liczb. Po zdefiniowaniu zmiennych jako double program zwraca bledne wartosci. Jak to poprawic, zeby wszystko ladnie dzialalo :d

#include <stdio.h>
#include <math.h>
int n, element;
float x, sinhx, sinh_math, licznik, mianownik, elementx, blad;
int main()
{

    printf( "Program liczy sinh(x), korzytajac z rozwiniecia w szereg Taylora.\nPodaj x: ");
    scanf( "%f", &x );    
    printf( "Podaj dokladnosc n: ");
    scanf( "%u", &n );
            /* czesc wlasciwa obliczajaca sinh(x) z szeregu Taylora */
            for ( element = 1; element <= n; ++element ){
                 mianownik = 2 * element - 1;
                 licznik = x;
                 for ( elementx = 1; elementx < mianownik; ++elementx ){
                     licznik = licznik * x;
                     }
                 for( --elementx; elementx >= 2; --elementx ){
                     mianownik = mianownik * elementx;
                     }
                 sinhx = sinhx + ( licznik / mianownik );
                 }
                 
    /* funkcja liczaca sinhx z biblioteki math.h */
    sinh_math = sinh(x);
    /* blad wzgledny */
    blad = (( sinhx - sinh_math) / sinh_math)*100;      
            
    printf( "sinh(%.2f) = %lf\n", x, sinhx);
    printf( "blad wzgledny wynosi: %lf", blad);
    return 0;
}
0

ja oddałem taki kod i zmaksowałem tą laborkę... poprzez analogię polecam przerobić :)

#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>

/* silnia obliczana rekurencyjnie */
float silnia(int n)
{
	if(n==1 || n==0)
		return 1;
	return n*silnia(n-1);
}

/* funkcja podnosi liczbe a do potegi b */
float potega(float a, int b)
{
	int i;
	float wynik = 1;
	for(i=0; i<b; i++)
		wynik *= a;   /* wynik = wynik * a */
	return wynik;
}

/* funkcja oblicza licznik tangensa hiperbolicznego */
float licznik(float x, int n)
{
	float wynik=0.0;
	int i;
	
	for(i=0; i<=n; i++)
		wynik += (1/(float)silnia(2*i+1))*potega(x, 2*i+1);
	return wynik;
}

/* funkcja oblicza mianownik tangensa hiperbolicznego */
float mianownik(float x, int n)
{
	float wynik=0.0;
	int i;
	
	for(i=0; i<=n; i++)
		wynik += (1/(float)silnia(2*i))*potega(x, 2*i);
	return wynik;
}

/* funkcja dzieli licznik tangensa hiperbolicznego przez jego mianownik :) */
float tgh(float x, int n)
{
	return licznik(x, n)/mianownik(x, n);
}

/* funkcja oblicza blad wzgledny porownujac wyniki napisanej powyzej funkcji obliczajacej
   tangens hiperboliczny oraz funkcji dostarczanej z bibliteka math */
float blad(float x, int n)
{
    float wynik = ((tanh(x)-tgh(x,n))/tgh(x,n))*100;
    if(wynik<0)
	wynik*=-1;
    return wynik;
}

int main()
{
/* kilka zmiennych */
	char Z[100];
	float x;
	char Y[100];
	int n;
	int correct=0;
/*******************/
	
	printf("\n" \
	"Grupa 1i3\n\n");
/* program wykonuje sie dopoki nie zostana wprowadzone poprawne dane */
while(correct == 0)
{
	printf("Podaj x: ");
	scanf("%s", Z);
	printf("Podaj n: ");
	scanf("%s", Y);
	
	x = atof(Z);
	n = atoi(Y);

	

	if((!x) || (!n))
	{
	    printf("Wprowadziles zero lub litere!\n" \
	    "Obliczenia dla zera nie maja sensu..\n" \
	    "Wprowadz poprawne dane!\n\n");
	} else if(n<0 || n>13)
	{
	    printf("n nie moze byc mniejsze od 0 ani wieksze od 13!\n");
	} else
	{
/*	printf("x = %f            n = %d\n", x, n);   */
	    printf("Wartosc mojej funkcji: tgh(%.4f)  = %f\n", x, tgh(x, n));
	    printf("Wartosc funkcji z math.h: tanh(%.4f) = %f\n", x, tanh(x));
/*	    printf("silnia: %.0f \n", silnia(n));*/
	    if(tgh(x, n) == 0)
	    {
		printf("Blad dzielenia przez 0! Obliczenia nie maja sensu :(\n" \
		"Wprowadz inne dane..\n\n");
	    } else
	    {
		printf("Blad wzgledny wynosi: %.2f%%\n\n", blad(x, n));
		correct=1;
	    }
	}
}
	return 0;
}
0

Tak, dawaj kod na konkretne zaliczenie publicznie, żeby kilkudziesięciu nieuków bezmyślnie skorzystało...

0

robilem podobnie, efekty podobne, ale mnie nie zadawalaja :P

0

popatrzyłem na kod s4ros, widzę "silnia" czyli już wiem, że źle :)
sinh(710)=1.116997383080855515626822229 E308
"daje do myślenia" co to była za reklama?

//q: ugh.. no ale zaliczyl.. tyle ze wieloryba..

1 użytkowników online, w tym zalogowanych: 0, gości: 1