C - metoda siecznych

?uco
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 19 sty 2010, o 20:29
Płeć: Mężczyzna
Lokalizacja: NET

C - metoda siecznych

Post autor: ?uco »

Witam.
Mam problem, nie wiem dlaczego ale coś niepoprawnie działa mi program do wyznaczania pierwiastków f. kwadratowej metodą siecznych...Czy mógłby mi ktoś pomóc i odnaleźć błąd??
Bo tyle patrze na to i nie mogę znalezc bledu

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
double kwa1(double x)
{int a,b,c,d;

d=a*x*x+b*x+c;
       return d;
       }       
              
int main(int argc, char *argv[])
{int i=64;
  float x0,x1,x2,f1,f2,f0,fkwa0,fkwa1,fkwa2;  
  int e,nr;
  float a,b,c,d;
printf("
======================================================================
");
     printf("podaj wspolczynniki a,b,c
");
    scanf("%f",&a);scanf("%f",&b);scanf("%f",&c); 
  printf("podaj x1,x2
");
    scanf("%f",&x1);scanf("%f",&x2);
  fkwa1=kwa1(x1);
  fkwa2=kwa1(x2);
  
  while (i>0 && abs(x1-x2)>0.000001)
  
  {
        if (abs(fkwa1-fkwa2)<0.000001)
        {
                                  printf("nie zostaly spelnone warunki/brak pierwiastkow
");
                                  break;
                                  }
                                  x0 = x1 - fkwa1 * (x1 - x2) / (fkwa1 - fkwa2); 
                                   fkwa0 = kwa1(x0); 
                                   if(fabs(fkwa0) < 0.000001){printf("przyblizony pierwiastek : %f
",x0);
                                   break;}
                                   x2 = x1;
        fkwa2 = fkwa1;
        x1 = x0;
        fkwa1 = fkwa0; 
        i--;
        if (i==0) printf("nie znaleziono pierwiastka
");break;} printf("======================================================================

");     
  printf("aby zakonczyc nacisnij ENTER");    
  while (!kbhit());	
  return 0;
}
A algorytm wygląda tak:

spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

C - metoda siecznych

Post autor: spajder »

1. formatowanie tego kodu to sieczka
2. funkcja kwa1 zwraca praktycznie wartość losową. Czy wiesz czemu? Obstawiam, że tu jest błąd.
3. widać, że nie wiesz, o co chodzi w tym algorytmie. Czy umiesz go wykonać na kartce?
4. swoją drogą funkcja kwadratowa nie jest najlepszą do testowania metody siecznych, bo ta wymaga pochodnej stałego znaku, więc trzeba kombinować z dobraniem przedziału. Domyślam się, że musisz to zrobić tą metodą.
?uco
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 19 sty 2010, o 20:29
Płeć: Mężczyzna
Lokalizacja: NET

C - metoda siecznych

Post autor: ?uco »

No właśnie mam zrobić to metodą siecznych..
Ad. 2. Dlaczego funkcja zwraca wartość losową( czyżby chodziło o współczynniki?);
Ad. 3. Dlaczego piszesz, że mój kod nie odpowiada algorytmowi? Mógłbyś mnie oświecić, co zrobiłem nie tak?Dopiero się uczę C więc nie wszystko jest dla mnie jasne.... Z góry dzięki...
Awatar użytkownika
Sokół
Użytkownik
Użytkownik
Posty: 451
Rejestracja: 17 wrz 2006, o 19:22
Płeć: Mężczyzna
Lokalizacja: Zielona Góra
Podziękował: 15 razy
Pomógł: 55 razy

C - metoda siecznych

Post autor: Sokół »

w funkcji kwal definiujesz lokalnie zmienne typu całkowitego a, b, c, d które inicjalizowane są z losowymi wartościami. To zupełnie inne zmienne niż te o tej samej nazwie, lecz typu float które są w funkcji main.-- 20 stycznia 2010, 18:39 -----
gwoli ścisłości, to nie losowymi wartościami, tylko wartościami takie, jakie były w pamięci, w miejscu w którego adres zmienne po definicji zyskały.

przez to funkcja kwal zwraca śmieci
?uco
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 19 sty 2010, o 20:29
Płeć: Mężczyzna
Lokalizacja: NET

C - metoda siecznych

Post autor: ?uco »

Aha....czyli jak to obejść z tymi zmiennymi lokalnymi?
Bo jak powiedzmy tam gdzie mam deklarowaną funkcję dodam scanf(..). to rozumie, że będzie pytać o współczynniki przy każdym użyciu funkcji w programie?
A czy mój program odpowiada algorytmowi, którego umieściłem w 1 poście?
Awatar użytkownika
Sokół
Użytkownik
Użytkownik
Posty: 451
Rejestracja: 17 wrz 2006, o 19:22
Płeć: Mężczyzna
Lokalizacja: Zielona Góra
Podziękował: 15 razy
Pomógł: 55 razy

C - metoda siecznych

Post autor: Sokół »

łuco pisze:Aha....czyli jak to obejść z tymi zmiennymi lokalnymi?
Bo jak powiedzmy tam gdzie mam deklarowaną funkcję dodam scanf(..). to rozumie, że będzie pytać o współczynniki przy każdym użyciu funkcji w programie?
A czy mój program odpowiada algorytmowi, którego umieściłem w 1 poście?
Albo stwórz zmienne globalne, przed funkcją main(), albo przekazuj współczynniki jako dodatkowe argumenty w funkcji kwal(), albo odwołuj się przez wskaźniki (ale skoro zaczynasz programować, to lepiej skorzystaj z której z dwóch pierwszych )

co do algorytmu - chyba tylko masz nieścisłości w komunikatach, sam kod wygląda na niezbyt dobrze (w sensie estetycznym) przerobiony z autorskiego rozwiązania z
spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

C - metoda siecznych

Post autor: spajder »

Nie twierdzę, że Twój kod nie odpowiada algorytmowi. Twierdzę, że wygląda na bezmyślnie przepisany.
?uco
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 19 sty 2010, o 20:29
Płeć: Mężczyzna
Lokalizacja: NET

C - metoda siecznych

Post autor: ?uco »

Sokół pisze: Albo stwórz zmienne globalne, przed funkcją main(), albo przekazuj współczynniki jako dodatkowe argumenty w funkcji kwal(),
Faktycznie chodzi o wiele lepiej...ale i tak coś nie dokońca hula:) np nie znajduje pierwiastków ujemnych np w funkcji kwadratowej..
A co do estetyki...to nie jest jeszcze ostateczne wersja więc jeszcze poprawię..
A zadanie moje polegało na odnalezieniu algorytmu i przerobieniu z języka c++ tyle że ma użytkownik podawać współczynniki a,b,c dla funkcji kwadratowej a nie dla "sztywnego" wyrażenia typu (sin(x)-1)*x..
Awatar użytkownika
Sokół
Użytkownik
Użytkownik
Posty: 451
Rejestracja: 17 wrz 2006, o 19:22
Płeć: Mężczyzna
Lokalizacja: Zielona Góra
Podziękował: 15 razy
Pomógł: 55 razy

C - metoda siecznych

Post autor: Sokół »

może problem leży w dobieraniu odpowiednich krańców przedziału? Nie znajduje pierwiastka nawet jeśli umieścisz tylko jedno (ujemne) miejsce zerowe między krańcami x1 i x2? Zobacz na jak działa ta metoda, pewne podane krańce nie gwarantują znalezienia rozwiązania. Poza tym, program podaje tylko jeden pierwiastek - wszystko w porządku jeśli podany przedział obejmuje tylko jeden, ale chyba tak byś nie musi. Nie wiem na ile musisz zmodyfikować ten algorytm, ale można by się pokusić np. o wyliczanie jednego pierwiastka, a drugi ze wzorów viete'a. Albo szukanie czy wierzchołek paraboli występuje w podanym przedziale i jak się zmieniają znaki funkcji. Twój projekt to myśl ;)
spajder
Użytkownik
Użytkownik
Posty: 735
Rejestracja: 7 lis 2005, o 23:56
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 2 razy
Pomógł: 133 razy

C - metoda siecznych

Post autor: spajder »

Niestety, tak się tego nie da. Metoda stycznych zakłada, że dwie pierwsze pochodne są stałego znaku - to znaczy, że funkcja jest w danym przedziale monotoniczna, czyli należy wziąć przedział nie zawierający ekstremum.
Idąc dalej - skoro funkcja jest monotoniczna to ma max. 1 pierwiastek (pomijam nieciekawy wyjątek). Tak więc ta metoda na pewno nie poda dwóch pierwiastków.
Spróbuj wziąć taki przedział jak mówię, np. dla funkcji
\(\displaystyle{ f(x) = x^2-4}\)

sprawdź przedział \(\displaystyle{ [-3, -1]}\)

A jak nie to licz na kartce i zobaczysz, co w tym programie jest źle.
ODPOWIEDZ