Obliczanie wartości wielomianu

0

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

0

pętla for, w której zwiększasz zmienna o zadany krok. i w zasadzie tyle

0

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.

0

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 ;)

0

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.

0
_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.

W = 2x<sup>3-x</sup>2+x-4 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.

0
Lander00 napisał(a):

... 2x3-x2+x-4=0 ...

Endrju napisał(a):

... W = 2x<sup>3-x</sup>2+x-4 ...
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.

0

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 :)

0

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.

0

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 :)

0
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.

0

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;
}
0

(( x + x - 1 ) * x + 1 ) * x - 4

0

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.

0
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); 
        }
}
0

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);
     }
  }

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