Puchacz1 Opublikowano 14 Kwietnia 2011 Zgłoś Opublikowano 14 Kwietnia 2011 napisałem takie malutkie narzędzie do liczenia przybliżonego pola pod całką met. Czebyszewa jednak zastanawia mnie skąd biorą się tak duże zaokrąglenia w obliczeniach między mną a np. kalkulatorem online. Na przykład dla n=2 i przykładu x^2+2x+1 mój kalkulator wyświetla 39.0 a kalkulator online 38.99250. Oczywiście ja stosuję double więc teoretycznie powinienem otrzymać dość dokładny wynik. Liczyłem kalkulatorem i to mój program tak dziwacznie zaokrągla. Ja tego nie chcę wobec czego chciałbym się dowiedzieć jak to zmienić :) double czebyszew(double *wezly, int a, int b, int n, double *xxx){ int rozmiar = 4; //musi być dynamicznie. double suma = 0; for(int i=0; i<rozmiar; ++i) { suma = suma + (xxx[1]*pow(wezly[i],xxx[2])+xxx[3]*pow(wezly[i],xxx[4])+xxx[5]*pow(wezly[i],xxx[6])); //cout << suma << " = " << xxx[1] << " * " << pow(wezly[i],xxx[2]) << "+" << xxx[3] << " * " << pow(wezly[i],xxx[4]) << "+" << xxx[5] << " * " << pow(wezly[i],xxx[6]) << endl; } return suma;}problemy zaczynają się w tej funkcji. O ile tablica wezly[] jest ok i wydawać by się mogło, że zwróci dokładny wynik to przy kolejnych obrotach pętli wynik jest po prostu zaokrąglany. Niby wynik nie jest jakiś z kosmosu różny ale jednak. Po zwrócenia sumy robię jeszcze tak: double calka = ((b-a)/n) * czebyszew(parametry); może coś doradzicie. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 14 Kwietnia 2011 Zgłoś Opublikowano 14 Kwietnia 2011 Zamieść kompletny kod. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
medive Opublikowano 14 Kwietnia 2011 Zgłoś Opublikowano 14 Kwietnia 2011 może błąd jest gdzieś w wywołaniu, bo na razie widzę że wkleiłeś tu tylko problematyczną klasę Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
MaciekCi Opublikowano 14 Kwietnia 2011 Zgłoś Opublikowano 14 Kwietnia 2011 napisałem takie malutkie narzędzie do liczenia przybliżonego pola pod całką met. Czebyszewa jednak zastanawia mnie skąd biorą się tak duże zaokrąglenia w obliczeniach między mną a np. kalkulatorem online. Na przykład dla n=2 i przykładu x^2+2x+1 mój kalkulator wyświetla 39.0 a kalkulator online 38.99250. Oczywiście ja stosuję double więc teoretycznie powinienem otrzymać dość dokładny wynik. Liczyłem kalkulatorem i to mój program tak dziwacznie zaokrągla. Ja tego nie chcę wobec czego chciałbym się dowiedzieć jak to zmienić :) double czebyszew(double *wezly, int a, int b, int n, double *xxx){ int rozmiar = 4; //musi być dynamicznie. double suma = 0; for(int i=0; i<rozmiar; ++i) { suma = suma + (xxx[1]*pow(wezly[i],xxx[2])+xxx[3]*pow(wezly[i],xxx[4])+xxx[5]*pow(wezly[i],xxx[6])); //cout << suma << " = " << xxx[1] << " * " << pow(wezly[i],xxx[2]) << "+" << xxx[3] << " * " << pow(wezly[i],xxx[4]) << "+" << xxx[5] << " * " << pow(wezly[i],xxx[6]) << endl; } return suma;}problemy zaczynają się w tej funkcji. O ile tablica wezly[] jest ok i wydawać by się mogło, że zwróci dokładny wynik to przy kolejnych obrotach pętli wynik jest po prostu zaokrąglany. Niby wynik nie jest jakiś z kosmosu różny ale jednak. Po zwrócenia sumy robię jeszcze tak: double calka = ((b-a)/n) * czebyszew(parametry); może coś doradzicie. Czyżby Politechnika Gdańska ? ;) Swoją drogą użyj long double'a i zmień funkcję cout na odpowiedniego printfa (np. %1.9f ) , u mnie przy liczeniu macierzy metodą Gaussa to pomogło. :) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Puchacz1 Opublikowano 16 Kwietnia 2011 Zgłoś Opublikowano 16 Kwietnia 2011 (edytowane) Nie, nie Gdańsk ;). Oczywiście printf pomogło. Zauważyłem jednak, że sama funkcja chyba liczy coś nie tak. Czasem daje dziwne wyniki i nie wiem czym to jest spowodowane. #include <iostream>#include <cmath>#include <cstdio>using namespace std;long double *wprowadz(){ long double wprowadzone[9] = {0,0,0,0,0,0,0,0,0}; cout << "Podaj liczbę węzłów (max.7)" << endl; cin >> wprowadzone[0]; // cout << "podaj współczynnik a: " << endl; cin >> wprowadzone[1]; cout << "podaj potege x: " << endl; cin >> wprowadzone[2]; // cout << "podaj współczynnik a: " << endl; cin >> wprowadzone[3]; cout << "podaj potege x: " << endl; cin >> wprowadzone[4]; // cout << "podaj współczynnik a: " << endl; cin >> wprowadzone[5]; cout << "podaj potege x: " << endl; cin >> wprowadzone[6]; // cout << "podaj poczatek przedzialu: " << endl; cin >> wprowadzone[7]; cout << "podaj koniec przedzialu" << endl; cin >> wprowadzone[8]; return wprowadzone;}long double *ti(int n){ //pierwszy element tablicy jest jej rozmiarem. //drugi element tablicy jest rozmiarem tworzonej tablicy x'ów if(n==2) { long double *t = new long double [3]; t[0] = 3; t[1] = 2; t[2] = 0.577350; return t; } else if(n==3) { long double *t = new long double [5]; t[0] = 5; t[1] = 6; t[2] = 0.707107; t[3] = 0.000000; t[4] = 0.707107; return t; } else if(n==4) { long double *t = new long double [6]; t[0] = 6; t[1] = 8; t[2] = 0.794654; t[3] = 0.187592; t[4] = 0.187592; t[5] = 0.794654; return t; } else if(n==7) { long double *t = new long double [6]; t[0] = 6; t[1] = 7; t[2] = 0.883862; t[3] = 0.529657; t[4] = 0.323912; t[5] = 0; } else { return 0; }}long double *zbiornik(int n, int a, int b){ long double *t = ti(n); int rozmiar = t[1]; // 2 element tablicy, poznaję rozmiar tablicy! cout << "t[1]: " << rozmiar << endl; int z = 2; long double *x = new long double [rozmiar]; for(int i=0; i<rozmiar; i+=2) { x[i+1] = (0.5)*(b + a) + ((0.5)*(b - a) * t[z]); x[i] = (0.5)*(b + a) + ((0.5)*(b - a) * (t[z] * (-1))); z++; cout << x[i] << " :x: " << x[i+1] << endl; } return x;}long double czebyszew(long double *wezly, int a, int b, int n, long double *xxx){ int rozmiar = 2; //musi być dynamicznie. Nie wiem jak sprawdzić rozmiar tablicy wezly[]. Jakaś sztuczka z sizeof() pewnie. long double suma = 0; for(int i=0; i<rozmiar; ++i) { suma = suma + (xxx[1]*pow(wezly[i],xxx[2])+xxx[3]*pow(wezly[i],xxx[4])+xxx[5]*pow(wezly[i],xxx[6])); //cout << suma << " = " << xxx[1] << " * " << pow(wezly[i],xxx[2]) << "+" << xxx[3] << " * " << pow(wezly[i],xxx[4]) << "+" << xxx[5] << " * " << pow(wezly[i],xxx[6]) << endl; } return suma;}void wypisz(long double *co, int n){ for(int i=0; i<n; ++i) //funkcja na razie nie potrzebna. { cout << co[i] << endl; }}int main(){ //long double *dane = wprowadz(); //funkcja działa ale dla sprawdzenia kodu stosuje tablice [opis poniżej] long double dane[9] = {2,1,5,2,2,1,0,1,4}; //pierwsze od lewej "2" to nasze n. wyrażenie jest w postaci z*x^c + z2*x^c + z*x^c. Ostatnie dwie cyfry to przedział (od 1-4, można zmienić). Całość w ogóle można zmienić, pamiętając jednak, że zaimplementowane jest jedynie n=2,3,4,7. int n = dane[0]; int a = dane[7]; int b = dane[8]; long double *x = zbiornik(n, a, b); long double wynik = (czebyszew(x, a, b, n, dane)*(b-a))/n; // tu kończymy prace mnożąc wynik przez (b-a)/n printf("%1.10Lf", wynik); return 0;} może Wy mi wskażecie błąd. Edytowane 16 Kwietnia 2011 przez Puchacz1 Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...