Zły wynik metodą bisekcji

0

Witam.
Muszę rozwiązać f-cję metodą bisekcji. Problem jest następujący: gdy liczę f-cję podaną w zadaniu na liczbach typu double, program zwraca NAN, jeżeli zmienię na long double, program działa ale zawsze zwraca -2, co jest błędem (wynik policzony przy pomocy wolfram:x=0.00258516). Mam też f-cje sprawdzającą działanie programu (bardzo prosta) i dla niej działa poprawnie na liczbach double, źle na long double. Nie potrafię znaleŹć błędu który powoduje takie działanie.

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<iomanip>
using namespace std;
long double bisek(long double(*funkcja)(long double),long double a,long double b,long double epsilon)
       {
       long double ya, yb, x, y;
       ya=funkcja(a);//licznie wartosci f-cji w koncach przedzialu
       yb=funkcja(b);
       if(ya*yb>=0)//sprawdzenie czy wewnątrz przedziału smienia się znak f-cji, czy jest miejsce zerowe w tym przedziale
                  {
                   return NAN;//jezli nie ma 
                  }   
       		do //jesli jest
            {
            x=(a+b)/2;//zmniejsz przedał 
            y=funkcja(x);//policz wartosc w nowym koncu
                    if(y==0)
                            {
                            return x;
                            }
                    if(ya*y<0)//sprawdz znak f-cji w nowym przedziale
                              {
                              b=x;
                              yb=y;
                              }
                    else 
                         {
                         a=x;
                         ya=y;
                         }
            }
            while(fabs(b-a)>epsilon);//wykonuj dopoki przedzial jest wiekszy od epsilon
            return x;      
       }
       
long double funkcja1(long double x)//f-cja którą muszę policzyć 
       { 
       return ((0.518*223.0)/(x-0.0018707))-(12.612620/(x*(x+0.0012707)*sqrt(223.0)))-65000.0;
       }
double funkcja2(double x)//f-cja do sprawdzania dzialania programu
       {
       return (x-2.13)*(x-2.13)*(x-2.13);
       }
	
int main()
    {
    cout.precision(10);
    int nr;
    long double (*funkcja)(long double), a, b, epsilon=1e-16,x;
    cout<<"podaj a:";
    cin>>a;
    cout<<"\npodaj b:";
    cin>>b;
    cout<<"\nfunkcje do wyboru:\n1: f-cja\n2: f-cja sprawdzajaca:\n"<<endl;
    cout<<"\nPodaj numer funkcji:";
    cin>>nr;
    switch(nr)
    {
    case 0:
         cout<<"to nie jest nr funkcji!";
         break;
    case 1:
         funkcja = funkcja1;
         break;
    /*case 2:
       	 funkcja = funkcja2;
         break;*/
    default:
         cout<<"to nie jest nr funkcji!";
         break;
    } 
    x=bisek(funkcja, a, b, epsilon);
    
    cout<<"miejsce zerowe funkcji to:"<<x<<endl;
    system("PAUSE");
    return 0;
} 
0
zgon napisał(a):

... program działa ale zawsze zwraca -2, co jest błędem (wynik policzony przy pomocy wolfram:x=0.00258516).

Czegoś nie rozumiem:
http://ideone.com/HkCO46
Może wyjaśnisz?

0

Nie pomyślałem żeby sprawdzić wynik. I tez nie rozumiem, ręcznie nie umiem tego policzyć. W przedziale z wykresu wynik także jest -2.(w danym przedziale f-cja spełnia warunki bisekcji),jeżeli podam mniejsze liczby to pojawia się inny wynik ale też zły. Lecz nie zmienia to faktu że program nie działa dla tej f-cji, a dla f-cji sprawdzającej działa. F-cja jest równaniem Redlicha-Kwonga z podstawionymi wartościami http://pl.wikipedia.org/wiki/R%C3%B3wnanie_Redlicha-Kwonga. Mogłem się pomylić w przepisywaniu ale sprawdzałem i nie zauważyłem błędu. Moim x jest Vm. http://imgur.com/QGpAFSb - wykres także z wolfram

0

if(y==0) tak nie porównuje się liczb zmiennoprzecinkowych
jakie dajesz a i b? Pamiętaj, że ta metoda działa tylko dla ciągłych funkcji.

0

próbowałem już z różnymi a i b ale wynik był zawsze -2 nawet jeżeli przedział dawałem od -1, a funkcja ma być ciągła w przedziale który sprawdzamy i tu się zgadza, jeżeli odczytując z wykresu dam przedział od 0.01 do 0.05 to wynik jest -2, a to nawet nie jest blisko przedziału

0

Ma być ciągła oraz przecinać oś X, obejrzyj link który podałem, tam są podane a i b oraz jest wynik.

0

UsL0Ecg.png

podając twoje dane otrzymuje taki wynik.

dodanie obrazka do załączników posta - @furious programming

0

W takim razie cofnij ostatnie zmiany.

0

ale jakie zmiany tam są wprowadzone?

0

Tu http://ideone.com/fGR3nP masz dowód że podany przez ciebie kod przy podaniu danych: 0.002 0.003 1 daje wynik: 0.002664269287
Jeżeli masz inny efekt oznacza to że kompilujesz i uruchamiasz inny kod niż ten co podałeś, i tu są dwie możliwości:

  1. Zrobiłeś jakieś zmiany po podaniu kodu na forum.
  2. Kompilujesz i uruchamiasz nie to co widzisz na ekranie.
0

Problem mam cały czas. Gdyby mi działało to bym nie prosił o pomoc. Może to być związane z tym, że korzystam z dev cpp, ale niestety muszę bo profesorowie też korzystają z tego, a jak coś sie nie kompiluje u nich to z góry jest nie zaliczone, więc staram się mieć oprogramowanie jak najbardziej zbliżone to tego co mają inni, teraz instaluje visual i spróbuje uruchomić jeszcze raz, ale to chwile zajmie.

0

Jak nie radzisz sobie z DevCpp to w Visualu na dzień dobry się pogubisz.
Pewnie założyłeś projekt w którym dodałeś plik A.cpp natomiast oglądasz i wklejasz na forum B.cpp zaś kompilujesz i uruchamiasz cały czas A.cpp

0

nie robię projektu, tworze tylko plik źródłowy .cpp i go kompiluje, teraz kopiowałem ten kod 2 razy do nowych plików, robionych tylko dla sprawdzenia i zawsze to samo, a kod który wkleiłem na początku mam jeszcze w innym miejscu zapisany

0

No to właśnie ten wklejony na początku jest poprawny, owszem trochę bezsensownie napisany ale nie o tym teraz mowa.

0

uzdolniony w tym kierunku nie jestem i na razie wole gorszy kod, ale taki który rozumiem, niż wypasiony, ale nie wiem jak działający, a co do kodu to masz rację uruchomiłem na komputerze znajomego (też w devcpp) i wszystko działa, czyli jakiś problem jest z moim komputerem. Zrobię reinstal dev'a może pomoże. Dzięki

0

Zacznij od restartu komputera i zacznij czytać komunikaty.

0

Tak ci trudno napisać funkcja że musisz za każdym razem słowo skracać zaoszczędzając dwa naciśnięcia klawiszy?

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