Wyszukiwanie miejsca zerowego funkcji

0

Witam,
mam za zadanie napisać następujący program:

Funkcja double f(double x) oblicza wartość funkcji f(x)

Napisz funkcję double rozwiazanie(double a, double b, double eps) która dla zadanych końców przedziału [a,b] ( gdzie a < b oraz f(a) x f(b) < 0 ) znajduje miejsce zerowe funkcji f(x)=0, dla a < x < b z zadaną dokładnością epsilon > 0 (znaleziona wartość nie różni się od faktycznej o więcej niż epsilon)

Przetestuj swój program dla f(x)=cos(x/2), a=2, b=4 i epsilon należy do {10-k : k=1,2,...8}

Napisałem taki oto program

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

double f(double x)
{
	return cos(x*0.5);
}

double rozwiazanie(double a, double b, double eps)
{
	double x;

	for(x=a;x<=b;x+=eps)
	{
		if(f(x) < eps && f(x) > -eps)
		{
			return x;
		}
	}
	
	return 0;
}

int main()
{
	double a=2.0;
	double b=4.0;
	double eps;
	int k;
	
	if( (a>=b) || ( f(a) * f(b) >= 0.0) )
	{
		printf("Niepoprawne dane\n");
	}

	for(k=1;k<=8;k++)
	{
		eps = 1.0/(pow(10.0, k));

		printf("Miejsce zerowe dla k = %d to %.10lf\n", k, rozwiazanie(a, b, eps) );
	}

	return 0;
}

Program oczywiście działa bez problemu, jednak po konsultacji z wykładowcą okazało się, że źle zrozumiałem treść zadania: nie mogę traktować eps jako dozwolone odstępstwo wartości funkcji, skoro eps ma jedynie mówić o dokładności oszacowania miejsca zerowego.

Próbowałem zmienić mój kod tak, aby pasował do polecenia, ale zupełnie nie mam pomysłu jak się za to zabrać, dlatego proszę o Państwa pomoc. Oczywiście nie proszę o gotowy kod, tylko jakąś wskazówkę jak "ugryźć" to zadanie.

1

Dopóki długość przedziału jest większa niż eps dziel przedział na dwie połowy i wybieraj taką połowę [c,d], że f(c)*f(d) <= 0

0

Dziękuję za odpowiedź, czy chodziło Panu o coś takiego?

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

double f(double x)
{
	return cos(x/2.0);
}

double rozwiazanie(double a, double b, double eps)
{
	double mzer=0.0;

	while( fabs(b-a)>eps )
	{
		mzer=(a+b)/2.0;

		if(f(mzer)==0.0)
		{
			return mzer;
		}

		if( f(a)*f(mzer) <= 0.0)
		{
			b = mzer;
		}
		else
		{
			a = mzer;
		}
	}

	return mzer;
}

int main()
{	
	double a = 2.0;
	double b = 4.0;
	double eps;
	int k;
	
	if( (a>=b) || ( f(a) * f(b) >= 0.0) )
	{
		printf("Niepoprawne dane\n");
	}

	for(k=1;k<=8;k++)
	{
		eps = 1.0/(pow(10.0, k));

		printf("Miejsce zerowe dla k = %d to %.10lf\n", k, rozwiazanie(a, b, eps) );
	}

	return 0;
}
0

Prawie o to mi chodziło. Ja bym opuścił to:

        if(f(mzer)==0.0)
        {
            return mzer;
        }
0

Rozumiem, dziękuję za odpowiedź.

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