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
Obliczanie wartości wielomianu
- Rejestracja: dni
- Ostatnio: dni
- Postów: 3
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2520
pętla for, w której zwiększasz zmienna o zadany krok. i w zasadzie tyle
- Rejestracja: dni
- Ostatnio: dni
- Postów: 61
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 353
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 ;)
- Rejestracja: dni
- Ostatnio: dni
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.
- Rejestracja: dni
- Ostatnio: dni
_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.
- Rejestracja: dni
- Ostatnio: dni
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 3
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 :)
- Rejestracja: dni
- Ostatnio: dni
- Postów: 91
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.
- Rejestracja: dni
- Ostatnio: dni
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 :)
- Rejestracja: dni
- Ostatnio: dni
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 3
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;
}
- Rejestracja: dni
- Ostatnio: dni
(( x + x - 1 ) * x + 1 ) * x - 4
- Rejestracja: dni
- Ostatnio: dni
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.
- Rejestracja: dni
- Ostatnio: dni
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);
}
}
- Rejestracja: dni
- Ostatnio: dni
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);
}
}