Misiek Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 Mam napisać program liczący sumę od i=0 do nieskończoności z (x^i)/i! czyli w skrócie e^x. x ma być podane przez użytkownika, podobnie jak epsilon, program ma liczyć do momentu, kiedy (x^i)/i! < epsilon. Nie bardzo wiem jak jak to ma po kolei działać... od czego mam zacząć, skąd wziąć wartość i, bo samo napisanie funkcji na silnie, tudzież na potęgę (tu C++ ma gotową funkcję pow(podstawa, wykładnik)) jest łatwe. Cytuj Odnośnik do komentarza
Glapa Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 proponuję zacząć to pętli for(int i=0;(x^i)/i!>=epsilon;i++) a w niej zawierasz obliczenia tej potęgi i silni silnie zapisujesz jako s=s*(s+1) przez co i będzie sie zwiekszać o 1 z kazdym wykonaniem dodawania a warunek konczący to ten wyraz mniejszy od epsilon Cytuj Odnośnik do komentarza
Misiek Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 no dobra, ale jak w warunku stopu dać silnię? coś takiego próbowałem: #include <iostream> #include <cmath> using namespace std; int main() { double x, eps; cout<<"Podaj x:"<<endl; cin >>x; cout<<"Podaj epsilon:"<<endl; cin>>eps; for (int i=0; pot/sil >=eps;i++) { double sil, pot; sil=sil*(sil+1); pot=pow(x,i); } } ale mi wywala, że "pot" i "sil" nie zadeklarowane Cytuj Odnośnik do komentarza
jasonx Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 A spróbuj zdeklarować przed forem? Cytuj Odnośnik do komentarza
adamus Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 musisz zadeklarować przed pętlą Cytuj Odnośnik do komentarza
jasonx Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 A jesli main jest intem, to nie musi być returna? Cytuj Odnośnik do komentarza
jakubkwa Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 Powinien być, ale AFAIR to kompilatory se radzą bez niego A co do kodu - silnię się jednak z tego co pamiętam liczy trochę inaczej - w kolejnych iteracjach robimy s=s*i (oczywiście trzeba uważać z wartością początkową i=0, albo trza walnąć ifa, albo jakoś sprytniej to zapisać), bo z s=s*(s+1) to nie wiem co wyjdzie Druga rzecz - chwilowo w ogóle nie liczysz sumy, tylko jej kolejne składniki, a chyba nie o to chodzi. Cytuj Odnośnik do komentarza
Misiek Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 tak tak tylko zapomniałem o deklaracji zmiennych, że powinny być przed forem i chciałem dać ten fragment co mam, żeby wybadać czemu jest nie tak. Co do silni to znalazłem przed chwilą gotową funkcję i wzór jest jeszcze inaczej double silnia (double n) { if (n==0) return 1; if (n==1) return 1; return silnia (n-1)*n; } Cytuj Odnośnik do komentarza
jasonx Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 #include "stdafx.h" void main () { int x; double silnia=1; do { printf ("podaj x>0: \n"); scanf("%d",&x); } while (x<1); for (int i=1;i<=x;i++) { silnia=i*silnia; } printf("silnia %d wynosi: %.0lf",x,silnia); flushall (); getchar (); } Masz działajacy program na silnie Cytuj Odnośnik do komentarza
jakubkwa Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 Co do silni to znalazłem przed chwilą gotową funkcję i wzór jest jeszcze inaczej double silnia (double n) { if (n==0) return 1; if (n==1) return 1; return silnia (n-1)*n; } No tak, to jest funkcja rekurencyjna, tylko jeśli chciałbyś jej użyć w tym programie i w każdej iteracji wywoływać silnia(i), to stanowczo Ci to odradzam, bo w tym wypadku za każdym razem wartość funkcji liczona jest od nowa. Lepiej wykorzystać fakt, że tu jest już jakaś iteracja i przy okazji sobie obliczać silnię. Ja ten program - bazując na Twoim rozwiązaniu - napisałbym tak: #include <iostream> #include <cmath> using namespace std; int main() { double x, eps, sil, pot, sum; cout << "Podaj x:" << endl; cin >> x; cout << "Podaj epsilon:" << endl; cin >> eps; if (eps > 1) cout << 1; // przypadek brzegowy -> dla i=0 wartość x^i/i! = 1 dla dowolnego x, a więc jeśli eps > 1 to eps > x^i/i!, więc warunek zakończenia pętli jest spełniony i nie ma po co w nią wchodzić else { sum = sil = 1.0; // wartości początkowe są takie, jakie byłyby w przypadku policzenia x^i/i! dla i=0 pot = x; // j.w. for (int i=1; pot/sil >= eps; i++) // wartości dla i=0 mamy ustawione jako początkowe, więc pętlę zaczynamy od i=1 { pot = pot*x; // nie wiem jak dokładnie działa pow(), ale podejrzewam że liczy wszystko od nowa podobnie jak rekurencyjna silnia, a więc tu - podobnie - liczymy sobie kolejne potęgi po drodze, mniejsza złożoność obliczeniowa gwarantowana sil = sil*i; sum += (pot/sil); // dodajemy do sumy kolejne jej składniki } cout << sum << endl; } return 0; } Cytuj Odnośnik do komentarza
Misiek Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 hmm, tyle, że dla x=2 suma powinna wynosić 7,3984 (e~2,72). Cytuj Odnośnik do komentarza
jakubkwa Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 No jasne, mój błąd, tam gdzie jest pot = x przed pętlą powinno być pot = 1.0. Cytuj Odnośnik do komentarza
Misiek Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 Jeszcze jednego tu nie rozumiem. Po co tutaj ten epsilon jest? Edit: No i czemu przy x=2 i epsilon=1, liczy równo 7, a nie powyżej 7? Cytuj Odnośnik do komentarza
Glapa Napisano 18 Marca 2009 Udostępnij Napisano 18 Marca 2009 epsilon jest po to żeby zakończyć tą sumę w pewnym miejscu bo jak wiadomo nieskończona suma (i tym samym pętla) się nie wykona a system wyrzuci błąd procesora. Cytuj Odnośnik do komentarza
jasonx Napisano 19 Marca 2009 Udostępnij Napisano 19 Marca 2009 jak z pliku przekazać dane do cstringa albo jak z chara do cstringa? CFileDialog x(TRUE); x.DoModal(); MessageBox("Otwiera plik "+x.GetPathName()); m_loc=x.GetPathName(); UpdateData(FALSE); m_tekst to zmienna cstring od editboxa która ma wyswietlać w nim tekst ale nie wiem jak to zrobić zeby do niej wbić dane z pliku Cytuj Odnośnik do komentarza
Misiek Napisano 30 Marca 2009 Udostępnij Napisano 30 Marca 2009 Znowu potrzebuje pomocy Polecenie: Zadeklarować dwa wektory n-elementowe np. 10-cio elementowe.1) napisać funkcję która losuje współrzędne wektora z przedziału <-4, 6> 2) napisać funkcję która wypisuje współrzędne wektora na ekran 3) obliczyć iloczyn oraz ilość tych współrzędnych wektora które są różne od 0, iloczyn ma być zwracany przez parametr typu referencyjnego zaś ilość elementów różnych od zera przez parametr typu wskaznikowego 4) napisać funkcję która zwraca wartość true jeśli wektory są prostopadłe w przeciwnym razie zwraca wartość false 5) napisać funkcję która oblicza i zwraca długość wektora 6) napisać funkcję która oblicza ile razy w wektorze występuje ujemna współrzędna, następnie przydziela dynamicznie pamięć na wektor o tej długości i przepisuje do niego ujemne wartości Mój fragment kodu: #include <iostream> #include <cmath> #include <iomanip> #define N 5 using namespace std; void losuj (int tab[N]); void wypisz (int tab[N]); void licz (int tab[N], int &iloczyn, int *ile); int main() { int wektor1[N]; int wektor2[N]; int iloczyn; int iloczyn1; int ile=0; int ile1=0; srand(time(NULL)); losuj(wektor1); losuj(wektor2); cout<<"Wektor pierwszy:"<<endl; wypisz(wektor1); cout<<endl; licz(wektor1, iloczyn, &ile); cout<<endl; cout<<"Wektor drugi:"<<endl; wypisz(wektor2); cout<<endl; licz(wektor2, iloczyn1, &ile1); cout<<endl; system("Pause"); } //polecenie 1 void losuj (int tab[N]) { for(int i=0; i<N; i++) { tab[i]=rand()%(6-(-4)+1)+(-4); } } //polecenie 2 void wypisz (int tab[N]) { for (int i=0; i<N; i++) { cout<<setw(4)<<tab[i]; } } //polecenie 3 void licz (int tab[N], int &iloczyn, int *ile) { for (int i=0; i<N; i++) { if (tab[i]!=0) { iloczyn=iloczyn*tab[i]; *ile=*ile+1; } else { iloczyn=0; cout<<"nie mozna mnozyc przez 0"<<endl; } } cout<<"Ilosc wynosi: "<<*ile<<endl; cout<<"Iloczyn wynosi: "<<iloczyn<<endl; } Mam kilka pytań co do polecenia 3: 1. Gdzie umieścić informację, że jak mam 0 ty wyskakuje komunikat, że nie można mnożyć przez zero? Bo w momencie dwóch 0 w wektorze, dostaje dwa komunikaty, co jest zrozumiałe 2. Dlaczego program potrafi jakoś beznadziejnie policzyć iloczyn? Np.: w jednym uruchomieniu z wektora1: 4 1 6 3 5 dostaje wynik -360? Skąd tu kurde ujemny a z wektora2: 6 6 -3 -3 2 dostaje wynik 508713024 ?? Niby ilość w obu podało poprawnie, po 5. Co do kolejnych poleceń, nie podawajcie gotowych rozwiązań, chcę najpierw sam zrobić, jak coś to będę pytał. Cytuj Odnośnik do komentarza
jasonx Napisano 30 Marca 2009 Udostępnij Napisano 30 Marca 2009 W trybie konsolowym CLR należy zbudować aplikację, która może obliczać za pomocą klasy macierz jedno z kilku działań (dodawanie, odejmowanie, mnożenie przez liczbę, transpozycja macierzy) bez Interfejsu Graficznego, lecz na wartościach zadanych lub podawanych z klawiatury za pomocą WE/WY. ma ktos moze przypadkowo gotowca na cos takiego? Cytuj Odnośnik do komentarza
lindros Napisano 30 Marca 2009 Udostępnij Napisano 30 Marca 2009 2. Dlaczego program potrafi jakoś beznadziejnie policzyć iloczyn? Np.: w jednym uruchomieniu z wektora1: 4 1 6 3 5 dostaje wynik -360? Skąd tu kurde ujemny a z wektora2: 6 6 -3 -3 2 dostaje wynik 508713024 ?? Niby ilość w obu podało poprawnie, po 5. W c++ zmiennym niezainicjalizowanym nie jest przypisawana domyślnie wartość zero(co i tak nie byłoby w tym przypadku dobre), jak to ma miejsce w języku c. W momencie inicjalizacji przypisz jej wartość 1. Ja po raz kolejny mam wrażenie, że polecenie jest totalnie niezrozumiałe. Co to znaczy, że wektory n-elementowe są prostopadłe? To tak, jakbyśmy rozpatrywali zagadnienie algebry wektorów w przestrzeni n-wymiarowej? Jesteś pewien, że w taki sposób można przekazywać do funkcji tablice w c++? Myślę, że zgrabnie byłoby to rozwiązać, stosując techniki obiektowe, ale wygląda na to, że jeszcze tego nie znasz, nie jest tak? Być może warto się zastanowić, czy losowanie współrzędnych nie łatwiej zrealizować w ten sposób: tab = 10*rand()-4; Cytuj Odnośnik do komentarza
Misiek Napisano 30 Marca 2009 Udostępnij Napisano 30 Marca 2009 Zagadnień obiektowych nie miałem. Co masz na myśli mówiąc przekazywanie tablic do funkcji? Chodzi Ci o wskaźniki i referencje? Wydaje mi się, że ok, zwłaszcza, że w innym programie tak robiłem i mi sprawdzał facet i powiedział, że ok. Co do losowania, to babeczka od wykładów podała, że losowanie z przedziału <MIN, MAX> robi się tak: x=rand()%(MAX-MIN+1)+MIN; a to co podałeś jakoś mi nie działa. Cytuj Odnośnik do komentarza
lindros Napisano 30 Marca 2009 Udostępnij Napisano 30 Marca 2009 Skoro coś działa i jest ok, to dobrze. Z losowymi się pomyliłem, rand nie zwraca ułamka od 0 do 1, jak mi się wydawało. Cytuj Odnośnik do komentarza
Rekomendowane odpowiedzi
Dołącz do dyskusji
Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.