C] Wprowadzanie funkcji (wielomianu) do programu

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Lolu9
Piegowaty Guziec
Piegowaty Guziec
Posty: 6
Rejestracja: 09 mar 2010, 15:47
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86

C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: Lolu9 »

Witam. Jestem początkującym programistą, więc proszę o odrobinę wyrozumiałości. Mam do wykonania program który będzie liczył pierwiastki wielomianu metodą bisekcji. Wielomian podaje użytkownik. I tu jest właśnie mój problem. Jak zabierałem sie do tego programu to najpierw napisałem taki który liczył pierwiastki z podanej funkcji (było ona w miejscu "return f(x)" zamiast "f(x)". O ile potrafię wczytać do tablicy kolejne współczynniki wielomianu, to nie mam pojęcia jak zrobić żeby program wczytał wielomian jako funkcje f(x).

Cały czas sam próbuje coś zdziałać ale będe wdzięczny za wszelkie wskazówki. Pozdrawiam i prosze o pomoc.

Kod: Zaznacz cały

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

double a,b,c,eps;
int n,i;
double wspol[6];

double f (double x)
{
	return f(x);
}
int main ()
{
	
	printf("Podaj stopień wielomianu: ");
	scanf("%d", &n);
	
	for (i=n ; i>=0 ; i--)
	{
		printf("a[%d]: ",i);
		scanf("%d", &wspol[i]);
	}
	
	printf("Podaj poczatek przedzialu: ");
	scanf("%lf", &a);
	printf("Podaj koniec przedzialu: ");
	scanf("%lf", &b);
	
	if (f(a)*f(b) >= 0) /* tw. Bolzano ? Cauchy?ego */
	{
    printf("Niewłaściwe dane wejściowe!");
    return 0;
	}
	
	printf("Podaj zadana dokladnosc: ");	
	scanf("%lf", &eps);
		
	while (b-a>eps)
	{
	c=(a+b)/2;
	
		if (f(a)*f(c)<0)
		b=c;
		
		else
		a=c;
	}
	
	printf("\nPierwiastek znajduje sie w punkcie x = %.4f",(a+b)/2);
		
	return 0;
}

EDIT:
Już sobie poradziłem. Ale może sie komuś przyda więc pokazuje poprawny kod:

Kod: Zaznacz cały

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


double wspol[6];

double f(double x)
{
	double r=0;
	
	for(int p=6-1;p>=0;--p) 
	r=r*x+wspol[p];
	
	return r;
}

int main ()
{
	double a,b,c,eps;
	int n,i;
	
	printf("Podaj stopień wielomianu: ");
	scanf("%d", &n);
	
		for (i=n ; i>=0 ; i--)
		{
			printf("a[%d]: ",i);
			scanf("%lf", &wspol[i]);
		}
		
	printf("Podaj poczatek przedzialu: ");
	scanf("%lf", &a);
	printf("Podaj koniec przedzialu: ");
	scanf("%lf", &b);
	
		if (f(a)*f(b) >= 0) /* tw. Bolzano ? Cauchy?ego */
		{
		printf("Niewłaściwe dane wejściowe!");
		return 0;
		}
	
	printf("Podaj zadana dokladnosc: ");	
	scanf("%lf", &eps);
		
		while (b-a>eps)
		{
		c=(a+b)/2;
	
			if (f(a)*f(c)<0)
			b=c;
		
			else
			a=c;
		}
	
	printf("\nPierwiastek znajduje sie w punkcie x = %.4f",(a+b)/2);
		
	return 0;
}
nwkj
Sędziwy Jeż
Sędziwy Jeż
Posty: 33
Rejestracja: 08 sie 2009, 14:53
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma

Odp: C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: nwkj »

Kod: Zaznacz cały

[34] artur@Zummi:/tmp> ./a.out 
Podaj stopień wielomianu: 1
a[1]: 1
a[0]: 0
Podaj poczatek przedzialu: -1
Podaj koniec przedzialu: 1
Podaj zadana dokladnosc: 0.000001

Pierwiastek znajduje sie w punkcie x = 1.0000
Coś tutaj nie gra... przecież pierwiastek jest w x = 0
-----------------------
  • Stopień wielomianu może wynosić co najwyżej 5, dlaczego nie n?
  • Nie sprawdzasz czy przypadkiem twoje c nie jest miejscem zerowym (przykład powyżej)
  • przy sprawdzaniu czy wartości na krańcach mają ten sam znak zamiast [ f(a) * f(b) < 0 ] lepiej jest używać sgn(f(a)) != sgn(f(b)), ze względu na niebezpieczeństwo wyzerowania się tego iloczynu.
Lolu9
Piegowaty Guziec
Piegowaty Guziec
Posty: 6
Rejestracja: 09 mar 2010, 15:47
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: Lolu9 »

  • Wielomian ma być maksymalnie 5 stopnia, bo takie polecenia dostałem od ćwiczeniowca :)
  • Dziękuje za wskazówke. Dodałem więc taki kod przed pętlą while:

    Kod: Zaznacz cały

                    if  ((f((a+b)/2))=0)
    		{
    		printf("Pierwiastek jest dokladnie w polowie podanego przedzialu i wynosi x = %.4f", (a+b)/2);
    		return 0;
    		}
  • Masz racje, żeby zrobić sgn, ale gdy tak robię to program mi sie nie kompiluje. Wydaje mi się, że jest mi potrzebna biblioteka, ale nie wiem jaka.
nwkj
Sędziwy Jeż
Sędziwy Jeż
Posty: 33
Rejestracja: 08 sie 2009, 14:53
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma

Odp: C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: nwkj »

Jeżeli to nie jest jakiś ważny program to możesz pominąć uwagę z mnożeniem... a sgn(x) to najlepiej sobie w tym wypadku napisać :-)
Lolu9
Piegowaty Guziec
Piegowaty Guziec
Posty: 6
Rejestracja: 09 mar 2010, 15:47
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: Lolu9 »

To myśle że sobie daruje :) Jeszcze raz dzięki.
nwkj
Sędziwy Jeż
Sędziwy Jeż
Posty: 33
Rejestracja: 08 sie 2009, 14:53
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma

Odp: C] Wprowadzanie funkcji (wielomianu) do programu

Post autor: nwkj »

Właśnie do mnie dotarło co napisałeś:

Dodanie tego kodu przed pętlą while nie wystarczy, sprawdzanie czy połowa jest miejscem zerowym musi być wykonywane dla każdego c (przecież miejsce zerowe może wypaść w połowie przedziału w którymś tam kroku), np.: f(x) = x na [-3, 1], miejsce zerowe nie wypada w c w pierwszym kroku ([-3, 1] ==> [-1.1] i wiemy co się stanie dalej...);
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 27 gości