Witajcie
Pan od programowania dał nam na zadanie domowe napisać program w c++, który będzie obliczał wartość wielomianu 2x3-x2+x-4=0 w określonym przedziale (np. od -20 do 20) i z ustalonym krokiem (np. co 1). Nie wiem nawet jak się zabrać za to. Nie chcę gotowego programu, tylko podpowiedzi, nakierowanie na odpowiedni tor. Dziękuje za każdą pomoc.
Lander00
pętla for, w której zwiększasz zmienna o zadany krok. i w zasadzie tyle
for ( pocztek = userInput(); pocztatek < ( koniec = userInput_static() ); poczatek+= userInput_static_krok() )
cout << power( (2*poczatek), 3-poczatek ) * 2 + pocztek - 4 << endl;
userInput_static() i userInput_static_krok muszą pobrać informację dokładnie raz.
Czego tu nie rozumiesz?
Masz jakis wzor funkcji:
f(x) = 2x3-x 2+x-4
No to robisz sobie funkcje
int count(int x)
{
return ...
}
Robisz petle ktora leci od -20 do 20 i wylicza wartosc tej funkcji w danym punkcie. Ty wypisujesz x i wartosc f(x) i tyle.
Edit. Ehh za szybcy jestescie ;)
Kika sekund w excel'u pokazuje że funkcja
f(x) = 2x3-x 2+x-4
Nie ma zer dla wartości całkowitych w przedziale [-20,20]
Kilka sekund zastanowienia pokazuje że ta funkcja nie istnieje dla liczb
ujemnych nie całkowitych ponieważ NIE MA potęgi ułamkowej z ujemnej liczby
czyli dla x=-0.5 x3-x = (-0.5)2.5 właściwie to wynik jest ale jest liczbą zespoloną.
Więc zadanie jakoś jest mało sensowne.
_13th_Dragon napisał(a):
Kika sekund w excel'u pokazuje że funkcja
f(x) = 2x3-x 2+x-4
Nie ma zer dla wartości całkowitych w przedziale [-20,20]
Kilka sekund zastanowienia pokazuje że ta funkcja nie istnieje dla liczb
ujemnych nie całkowitych ponieważ NIE MA potęgi ułamkowej z ujemnej liczby
czyli dla x=-0.5 x3-x = (-0.5)2.5 właściwie to wynik jest ale jest liczbą zespoloną.
Więc zadanie jakoś jest mało sensowne.
to wielomian. Akurat w tym przedziale ma biegun i jak każdy normalny wielomian jest określony w całym zbiorze liczb rzeczywistych. OP potrzebuje tylko pętli i ewentualnie schematu hornera (w takim przypadku to chyba będzie overkill) ale jest leniwy.
Lander00 napisał(a):
... 2x3-x2+x-4=0 ...
Endrju napisał(a):
... ...
Dopiero jak napisałeś do mnie dotarło że autor tematu zwyczajnie nie umie korzystać z tego forum.
można nie tylko tex'em zapisać zaś również zwyczajnie tak:
2x3-x2+x-4=0
wystarczy dwa dodatkowe daszki.
No przepraszam was panowie. Nie umiem korzystać. Wczoraj jakoś głowy nie miałem. Póki co wymyśliłem coś takiego
//wielomiany
#include<iostream>
using namespace std;
double k,p,l; //k - krok, p - poczatek przedzialu, l - koniec przedzialu
char C;
int main ()
{
cout << "Witaj. Oblicze dla ciebie wartosc wielomianu 2x^3-x^2+x-4 w przedziale zdefiniowanym przez ciebie i z wybranym przez ciebie krokiem." << endl;
cout << "Podaj krok" << endl;
cin >> k;
if (k<0)
cout << "przedzial musi byc dodatni" << endl;
else if (k>0)
{
cout << "podaj przedzial (od wartosci mniejszej do wiekszej)" << endl;
cout << "od ";
cin >> p;
cout << "do ";
cin >> l;
if (l<p) //jesli koniec przedzialu jest mniejszy od poczatku przedzialu
cout << "Zle podany przedzial (musi byc podany od wartosci mniejszej do wiekszej " << endl;
else if (k>-(p-l)) // jesli krok jest wiekszy niz ujemna roznica poczatku i konca przedzialu, to obliczy x tylko dla wartosci poczatkowej przedzialu
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << p << " wynosi: " << 2*p*p*p-p*p+p-4 << endl;
else
for (double x= p; x <=l; x=x+k)
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << x << " wynosi: " << 2*x*x*x-x*x+x-4 << endl;}
cin >> C;
return 0;}
Sprawdźcie jak możecie czy to całe działa. Wiem że można to inną metodą zrobić zapewne, ja zrobiłem taką. Mimo wszystko dziękuje za każdą pomoc :)
Nie używaj zmiennych o nazwach p, k, itp. To utrudnia pisanie i czytanie kodu. Lepiej pisać Poczatek, Koniec.
Zrób to na funkcjach. Większość programu masz niepotrzebnie w "else if".
Przed if'ami i else'ami nie daje się dodatkowych wcięć, ale po tym, co ma być w tym ifie/else'ie wykonane - tak.
Przed częścią kodu, która zajmuje się trochę "czym innym" dodawaj pustą linię.
Nie umieszczaj klamr zamykających w tej samej linii, w której jest kod.
Nie używaj zmiennych globalnych kiedy ich nie potrzebujesz, a tutaj ich nie potrzebujesz. Zmienne deklaruj na poczaku bloku, w którym będą używane, czyli w tym wypadku na początku funkcji main.
Znak nowej linii to nie endl a "\n". Nie używaj endl do robienia nowej linii, bo endl służy do wypychania danych ze strumienia.
Dziwnie formatujesz kod, w zasadzie to chodzi mi o duże wcięcia, szczególnie od razu po klamrze otwierającej blok funkcji main, zrobisz kilka takich wciec i dany wiersz nie zmieści Ci sięna ekranie monitora ;)
cin >> k;
if (k<0)
cout << "przedzial musi byc dodatni" << endl;
Zamiast powodowac wylaczenie programu przy podaniu złej wartości (jak w kodzie wyżej), proś usera do skutku, żeby podał dobrą :)
Np.
cin>>k;
while (k<0)
{
cout>>"Wartosc k musi byc wieksza od zera.\nPodaj k:\n";
cin>>k;
}
I jeszcze kwestia zamykających klamer. Umieszczaj je w osobnym wierszu, łatwiej je znaleźć, lepiej widać gdzie co się kończy :)
kaboom napisał(a):
Nie używaj zmiennych globalnych kiedy ich nie potrzebujesz, a tutaj ich nie potrzebujesz. Zmienne deklaruj na poczaku bloku, w którym będą używane, czyli w tym wypadku na początku funkcji main.
Po co. Jaki to w ogóle ma sens poza zmniejszeniem czytelności? Nawet w C zrezygnowali już z tego dziwacznego pomysłu. (Od C99) Zmienne powinny mieć jak najmniejszy zasięg i być definiowane w miejscu pierwszego użycia.
W tym jego kodzie akurat nie ma to większego znaczenia, ale to bardzo zła porada.
Troszkę zmodyfikowałem kod według waszych rad, jednak nie do końca. Jeszcze nie jestem jakoś szczególnie obeznany z c++ dopiero raczkuję. Jeśli chodzi o endl to tak używamy na lekcji, w każdym programie, który robimy. Także sam nie wiem jak z tym. Mam nadzieję, że teraz jest z kodem troszkę lepiej
//wielomiany
#include<iostream>
using namespace std;
int main ()
{
double krok,poczatek,koniec
char C;
cout << "Witaj. Oblicze dla ciebie wartosc wielomianu 2x^3-x^2+x-4 w przedziale zdefiniowanym przez ciebie i z wybranym przez ciebie krokiem." << endl;
cout << "Podaj krok" << endl;
cin >> krok;
while (krok<0)
{
cout << "Wartosc krok musi byc wieksza od zera." << endl;
cout << "Podaj krok:" << endl;
cin>>krok;
}
cout << "podaj przedzial (od wartosci mniejszej do wiekszej)" << endl;
cout << "od ";
cin >> poczatek;
cout << "do ";
cin >> koniec;
if (koniec<poczatek) //jesli koniec przedzialu jest mniejszy od poczatku przedzialu
cout << "Zle podany przedzial (musi byc podany od wartosci mniejszej do wiekszej " << endl;
else if (krok>-(poczatek-koniec)) // jesli krok jest wiekszy niz ujemna roznica poczatku i konca przedzialu, to obliczy x tylko dla wartosci poczatkowej przedzialu
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << poczatek << " wynosi: " << 2*poczatek*poczatek*poczatek-poczatek*poczatek+poczatek-4 << endl;
else
for (double x= poczatek; x <=koniec; x=x+krok)
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << x << " wynosi: " << 2*x*x*x-x*x+x-4 << endl;
cin >> C;
return 0;
}
(( x + x - 1 ) * x + 1 ) * x - 4
Tak bym to raczej zrobił jeżeli chodzi o samo formatowanie kodu (i endl :) ).
//wielomiany
#include<iostream>
using namespace std;
int main ()
{
double krok,poczatek,koniec;
char C;
cout << "Witaj. Oblicze dla ciebie wartosc wielomianu 2x^3-x^2+x-4 w przedziale"
" zdefiniowanym przez ciebie i z wybranym przez ciebie krokiem.\n";
cout << "Podaj krok\n";
cin >> krok;
while (krok<0)
{
cout << "Wartosc krok musi byc wieksza od zera.\n";
cout << "Podaj krok:\n";
cin>>krok;
}
cout << "podaj przedzial (od wartosci mniejszej do wiekszej)\n";
cout << "od ";
cin >> poczatek;
cout << "do ";
cin >> koniec;
if (koniec<poczatek) //jesli koniec przedzialu jest mniejszy od poczatku przedzialu
{
cout << "Zle podany przedzial (musi byc podany od wartosci mniejszej do wiekszej \n";
}
else if (krok>-(poczatek-koniec)) // jesli krok jest wiekszy niz ujemna roznica poczatku i konca przedzialu,
{ // to obliczy x tylko dla wartosci poczatkowej przedzialu
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << poczatek << " wynosi: ";
cout << 2*poczatek*poczatek*poczatek-poczatek*poczatek+poczatek-4 << "\n";
}
else
{
for (double x= poczatek; x <=koniec; x=x+krok)
{
cout << "Wartosc wielomianu 2x^3-x^2+x-4 dla x rownego " << x << " wynosi: " << 2*x*x*x-x*x+x-4 << "\n";
}
}
cin >> C;
return 0;
}
Oczywiscie klamerki przy jednolinijkowych forach/ifach nie są wymagane, jednak ja tam lubie je dawac. Jak nie w osobnych linijkach to w jednej, ale z klamrami.
Co do poprawności, Code::Blocks nie wywala błędów/ostrzeżeń, ale spróbuj dać krok 0 i zobaczysz co sie stanie :)
Edit: No i jeszcze dochodzi inne sprawdzenie, też daj je w while-do zamiast w ifa, bo jak podasz zły przedzial to niech upiera sie o dobry a nie konczy działanie :)
Edit2: I poczytaj o operatorach takich jak np += -= itp.
Zatrzymywanie programu pobieraniem chara to wiesz, że tylko do celów edukacyjnych? Tak samo jak inne funkcje typu system("PAUSE"), getch() itp.
inline double W(double x) {
return (( 2*x - 1 ) * x + 1 ) * x - 4; }
// pozbyłem się jednego mnożenia
// dwukrotne zapisanie formuły w programie uważam za błąd
main(void) {
double a,b,h,x,y;
int i,n;
/* cout, cin */
// mam w nosie sprawdzanie, bo klient ma zawsze rację ! :-)
// znak kroku (h) może być dowolny, znak (b-a) też
a=2; b=-2; h=-0.01;
if( fabs(h) > 1e-20 )
// tu można by/należałoby pokombinować z badaniem różnicy logarytmów
// albo wyjątkami, ale znacznie lepsze niż testowanie h==0
n = (b-a) / h;
else {
n = 1; h = b - a;
if( a==b ) n=0;}
if( n<0 ) {
n = -n; h = -h; }
for( i=0; i<=n; i++ ){
x = a + i*h; // napisanie x = x + h jest błędem
y = W(x);
printf("%5d w(%+f) = %+e\n", i, x, y);
}
}
Można trochę prościej wg mnie:
#include <stdio.h>
#include <math.h>
#define MAXSHOW 32000
int main(void)
{
double a,b,h,r,x;
int i,n;
for(;;)
{
printf("podaj a b h (!-koniec): ");
if(scanf("%lf%lf%lf",&a,&b,&h)!=3) return 0;
r=((b-a)/h);
if(isinf(r)||(r<-MAXSHOW)||(r>MAXSHOW)) r=MAXSHOW;
n=(int)fabs(r);
for(i=0,x=a;i<=n;++i,x=(a*(n-i)+b*i)/n) printf("%5d w(%+lf) = %+le\n",i,x,((2*x-1)*x+1)*x-4);
}
}