Program na uczelnię C - szereg, liczba e, silnia...

0

Mam do napisania na jutro coś takiego:
user image
i kompletnie nie wiem od czego mam zacząć, o co w tym w ogóle chodzi?!

Byłbym wdzięczny za jakiekolwiek wskazówki, pomoce... :)

0

Ja bym proponował zacząć naukę od mnożenia i dzielenia, to się tu przyda. Poza tym to chyba cała filozofia.

0

winter, nieprawda, filozofowie potrafią w większego niczego wyciągnąć większe i daleko bardziej idące wnioski

całkiem tanio znajdziesz tu wielu ludzi którzy wyssali to "e" z mlekiem matki
ja bym, ale nudy...

0

Wybaczcie, no... nie zabieram więcej czasu.

0

a zabieraj, jak tylko coś ciekawego znajdziem to zabijem twojego laboranta

0

Jestem dosłownie zielony jeśli chodzi o to, nie wiem co ja robię na tym kierunku...
Co muszę wyciągnąć z tego programu? e^x to exp(double x), ale co mam zrobić z prawą stroną? Co z tym szeregiem?

Miałem nie zabierać więcej czasu, ale jestem zdesperowany i szukam pomocy gdzie się da :P

0

Siema. Może pokombinuj z rozwinięciem w szereg Maclaurina/Taylora... Może to Ci pomoże:

http://wazniak.mimuw.edu.pl/index.php?title=Analiza_matematyczna_2/Wyk%C5%82ad_4:_Ci%C4%85gi_i_szeregi_funkcyjne._Szereg_Taylora

Przykładowo dla liczby x=2 Masz prawą stronę = ok. 7,3441. Teraz musisz w pętli for zrobić sumę tych wyrazów z rozwinięcia (powyższy link). Im więcej wyrazów weźmiesz tym prawa strona będzie mniej się różniła od lewej.

Musisz jeszcze zrobić obliczanie silni.

Wówczas w pętli for bierzesz dla liczenia np. 10 takich wyrazów. Czyli będzie obliczanie:
1, potem (W zależności jaką liczbę przyjąłeś dla x - np. 2) 2/1, potem 22/2! czyli 4/(1*2) = 4/2 = 2 :) potem 23/3! = 8/6 itd. Aż do wyrazu 2^10/10! Coś takiego. Mam nadzieje że wiesz o co kaman :)

3

Mam do napisania na jutro coś takiego:

Masz do napisania. To może napiszę ci ładniej - o, gotowca:

\mathrm{e}<sup>x =\sum_{n=0}</sup>\infty \frac{x^n}{n!}

\mathrm{e}^x =\sum_{n=0}^\infty \frac{x^n}{n!}

0

a z drugiej strony: 1+1/n do potęgi n, a "n" ucieka w nieskończoność
a "facepalm" jak najbardziej na miejscu gdy proponuje obliczenia silni

o jeszcze coś, to bardzo ładnie realizuje się na liczbach całkowitych, np. w Excelu można łatwo policzyć kilkaset cyfr rozwinięcia.

0

Masz dane rozwiniecie w szereg funkcji e^x i tyle, tak aby moc policzyc w przyblizeniu jej wartosci za pomoca tej sumy.

Jako ze to taki prosciutki program to masz... Tak w ogole nie wiedzialem ze long double przyjmuje az takie duze wartosci ;) przy samym double liczylo jedynie do 150 a przy long juz do 1250 okolo. Jesli nie rozumiesz kodu twoja sprawa ;p Nie bede tlumaczyl bo jest banalny.

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

long double silnia(int n)
{
    long double result=1;
    for(int i=1;i<=n;i++)
    {
        result*=i;
    }
    return result;
}

int main()
{
    long double eps,exp2=0,exp3=1,x,exp4=0;
    int licznik=0;
    cin >> eps;
    cin >> x;
    while(fabs(exp2-exp3)>eps)
    {
        exp3=exp2;
        exp2+=pow(x,licznik)/silnia(licznik);
        licznik++;
    }
    for(int i=0;i<3*x;i++)
    {
        exp4+=pow(x,i)/silnia((double)i);
    }
    cout << exp2 << " " << exp(x) << " " << exp4 << endl;
    system("pause");
    return 0;
}
2
Krycho napisał(a)

Program jest napisany dobrze. Dziala i liczy poprawnie wartosci wiec czepiaj sie kogo innego.

To, że program "działa dobrze" nie świadczy o tym, że jest dobrze napisany.

Krycho napisał(a)

Patrzec mozna tak ze widze tylko sume i pewien ulamek. Suma to dla mnie for ulamek to ulamek to co mam w nim dziele przez siebie i tyle, ciezko to zrozumiec?
Ciężko czy nie ale na pewno nie optymalnie. Nie poleciłbym takiego programisty nikomu.

Krycho napisał(a)

Nie siedze i nie rozpisuje sobie wzoru na kartce zeby sprawdzic jak wyglada jego rozwiniecie do miliardowego skladnika sumy...
Nie musisz znać rozwinięcia miliardowego składnika sumy jak i nie musisz rozpisywać tego na kartce. Po to jest wzór. Prawda jest taka kolego, że dałeś rozwiązanie (i chwała ci za to bo zrobiłeś dobry uczynek) ale nie potrafisz przyjąć do wiadomości słów krytyki, a widać po powyższej dyskusji, że są one uzasadnione.

0
double EXP( double x ){
	double s=1, w=1, i=1;
	while( w )                       // <----------------- ?
		s += w *= x / i++;
	return s;}
	
main(i){
	for(i=0; i<20; i++)
		printf("%d %f %f\n", i, exp(i), EXP(i)); }
0

@Xitami
Liczysz o wiele za daleko, niż powinieneś, nie uzyskując przy tym wzrostu dokładności wyniku. Już lepiej byłoby dać jakąś wartość maksymalną dla n i przesuwać się od niej do tyłu do osiągnięcia 1 (około), choć też tracisz trochę dokładności. Można przesuwać się normalnie i tablicować wyniki otrzymane do pewnego momentu i uciąć, gdy wartość składnika jest dostatecznie mała (dla liczb ujemnych i tak wystarczającej dokładności nie otrzymasz używając tego wzoru).

Nie wiem czy jest to wymagane w tym wzorze (choć dla dużych x różnica może się pojawić). Bez kombinowania możesz zmienić warunek na while (s!=s+w).

0
hohoho napisał(a)
Krycho napisał(a)

Program jest napisany dobrze. Dziala i liczy poprawnie wartosci wiec czepiaj sie kogo innego.

To, że program "działa dobrze" nie świadczy o tym, że jest dobrze napisany.

Krycho napisał(a)

Patrzec mozna tak ze widze tylko sume i pewien ulamek. Suma to dla mnie for ulamek to ulamek to co mam w nim dziele przez siebie i tyle, ciezko to zrozumiec?
Ciężko czy nie ale na pewno nie optymalnie. Nie poleciłbym takiego programisty nikomu.

Krycho napisał(a)

Nie siedze i nie rozpisuje sobie wzoru na kartce zeby sprawdzic jak wyglada jego rozwiniecie do miliardowego skladnika sumy...
Nie musisz znać rozwinięcia miliardowego składnika sumy jak i nie musisz rozpisywać tego na kartce. Po to jest wzór. Prawda jest taka kolego, że dałeś rozwiązanie (i chwała ci za to bo zrobiłeś dobry uczynek) ale nie potrafisz przyjąć do wiadomości słów krytyki, a widać po powyższej dyskusji, że są one uzasadnione.

Czas wykonania mojego programu dla krancowych wartosci ktore jest w stanie policzyc wynosi 0.02-0.03s, gdzie dla kodu xitami jest to tyle samo. O optymalnosci mozemy rozmawiac przy duzych projektach, gdzie czasy wykonania w zaleznosci od zlozonosci algorytmu O(n) czy O(n^2) sa znaczaco rozne. Wtedy moge optymalizowac taki kod. Tutaj to czy napisze to w taki sposob czy inny nie zmieni mi czasu wykonania, a jedynie moze liczyc wieksze wartosci. Z tego wzgledu bede sie klocil, bo przy innej sumie gdzie jak np. przy aproksymowaniu funkcji gdzie wzor na to jest zlozonych z 5 albo 6 sum czesciowych nie bede sie zastanawial jak te sumy moge sobie skrocic zeby program liczyl mi o milisekunde szybciej tylko przepisze sobie gotowy wzor na sume do kodu.

PS. Jesli tak wam zalezy na optymalnych rozwiazaniach to moim zdaniem lepiej pisac programy w assemblerze. Tam czasy wykonania w porownaniu z jezykami wysokiego poziomu znaczaco sie wam skroca dodatkowo mozecie implementowac wasze "optymalniejsze" rozwiazania i wszystko bedzie smigalo jak burza ;p

0

Zależy jeszcze dla jakiego komputera. Poza tym, sam jeszcze bardziej spowalniasz program (może i o małe jednostki czasu, ale po co to robić?).
Otóż wystarczy nawet popatrzeć tylko na implementację funkcji silnia.

double silnia(int i) {...}
// wywołanie
silnia((double)i); // serio? To jest nie tyle nieeleganckie, co poprostu brzydkie i niepotrzebne
0

Akurat te niepotrzebne konwersje usunalem po chwili, a ze pisac tamtego postac nie bylem zalogowany to nie moglem go wyedytowac.

1

Twój kod (pętla po eps i po x):

        for(int i=2;i<=10;i++)
        {
            double x=0.0001;
            double eps=Math.pow(10,-i);
            while(x<=1.0)
            {
                licznik=0;
                exp=0.0;
                oldExp=1.0;
                while(Math.abs(exp-oldExp)>eps)
                {
                    oldExp=exp;
                    exp+=Math.pow(x,licznik)/silnia(licznik);
                    licznik++;
                }            
                x+=0.0001;
            }
        }

Czas wykonania: około 200 ms.
Rozsądny kod:

        for(int i=2;i<=10;i++)
        {
            double x=0.0001;
            double eps=Math.pow(10,-i);
            while(x<=1.0)
            {
                licznik=1;
                exp=0.0;
                oldExp=1.0;
                skladnik=1.0;
                while(Math.abs(exp-oldExp)>eps)
                {
                    oldExp=exp;
                    exp+=skladnik;
                    skladnik*=x/licznik;
                    licznik++;
                }               
                x+=0.0001;
            }
        }

Czas wykonania: około 7 ms.
Wnioski wyciągnij sam.

0

200 czy 7, a co za różnica?
Istotne jest to czy rozumie się co się robi czy nie.

1
Krycho napisał(a)

PS. Jesli tak wam zalezy na optymalnych rozwiazaniach to moim zdaniem lepiej pisac programy w assemblerze. Tam czasy wykonania w porownaniu z jezykami wysokiego poziomu znaczaco sie wam skroca dodatkowo mozecie implementowac wasze "optymalniejsze" rozwiazania i wszystko bedzie smigalo jak burza ;p

Mnie nie chodzi o optymalizację związaną z językiem tylko z samym algorytmem. Zastosowanie odpowiedniego algorytmu w wymienianym przez ciebie assemblerze i tak zadziała szybciej niż twój algorytm. Problem jest na tyle błahy, że zaawansowany średnio programista (jak nie późno-początkujący) powinien ten wzór z 'automatu' sobie uprościć bez większych rozmyślań. To nie jest kwestia narzędzia, a raczej sposobu jego użycia.

0
hohoho napisał(a)
Krycho napisał(a)

PS. Jesli tak wam zalezy na optymalnych rozwiazaniach to moim zdaniem lepiej pisac programy w assemblerze. Tam czasy wykonania w porownaniu z jezykami wysokiego poziomu znaczaco sie wam skroca dodatkowo mozecie implementowac wasze "optymalniejsze" rozwiazania i wszystko bedzie smigalo jak burza ;p

Mnie nie chodzi o optymalizację związaną z językiem tylko z samym algorytmem. Zastosowanie odpowiedniego algorytmu w wymienianym przez ciebie assemblerze i tak zadziała szybciej niż twój algorytm. Problem jest na tyle błahy, że zaawansowany średnio programista (jak nie późno-początkujący) powinien ten wzór z 'automatu' sobie uprościć bez większych rozmyślań. To nie jest kwestia narzędzia, a raczej sposobu jego użycia.

To mnie nie powinni przepuszczac chyba na drugi rok i stawiac 5 z matmy. Naprawde napisz do mojego profesora bo to jest karygodne co ja zrobilem... Teraz bez ironii. Ideone przy moim kodzie pokazalo 0.02 co daje 20ms jesli jeszcze liczyc potrafie dobrze. Nie licze silnii rekurencyjnie tylko zlozonosc jest liniowa. To ze nie pamietam rozwiniecia tej funkcji to taki blad? dla mnie x^n/n! to po prostu tyle. Kiedy mam do czynienia z duzo bardziej skomplikowanymi sumami to nie mam czasu ani ochoty siedziec i sie zastanawiac, a moze da rade sie to skrocic? Nawet taki wzor interpolacyjny hermite'a, dali mi gotowy wzor to nie bede go na nowo tworzyl i rozwijal patrzac jak ma sie nastepny wyraz do poprzedniego z nadzieja ze cos skroce, tylko przepisze gotowe rzeczy do kompa.

Powtorze jeszcze jedna rzecz, ze o optymalizacji moge myslec przy duzych projektach, nie przy malych programikach, gdzie to czy sie wykona w 20ms czy 5ms, czy nawet 200ms nie zrobi mi zadnej roznicy, bo i tak tego nie zauwaze. Chyba ze chcecie sie pochwalic, ze wasz program jest szybszy od innych. W takim razie spoko...

1

Bardzo źle podchodzisz do zagadnienia. Jeżeli liczysz exp(x) z rozwinięcia w szereg tylko dla jednej wartości x, to czy czas wykonania wynosi 0,002 s, czy jest 30 razy dłuższy nie ma żadnego znaczenia. Ale nie wiesz czy napisany przez Ciebie kod nie zostanie użyty w rozbudowanym programie do wielokrotnego obliczania exp(x). A wtedy 30-krotne spowolnienie jest bardzo istotne. Zauważ też, że Twój zdecydowanie wolniejszy kod jest bardziej skomplikowany od kodu szybszego, naprawdę nie masz czego bronić.
Powołujesz się na 5 z matematyki, jeżeli Ty nie widzisz od razu, że xn/n!=(xx....x)/123*...*n, to ta ocena jest co najmniej o 2,5 za wysoka.

0

Jedyne co widze patrzac na sume xn/n! to x0/0! + x1/1! + x2/2! + ... + x^n/n!. No ale niestety tak mnie nauczyli to rozwijac ;((. Akurat w tym wypadku wiem, bo mowil co jest jego zadaniem. Tak wiec po prostu w zaleznosci od sytuacji moge sobie pozwolic na pewne nazwijmy to ulatwienia z mojej strony. Jak mowilem w wiekszym projekcie juz to podejscie byloby zapewne inne.

0

ta funkcja też "działa", tyle, że kubicznie

#include <stdio.h>
#include <string.h>

int palindrom(char t[]){
	int i;
	for( i=0; i<strlen(t); i++ )
		if( t[i] != t[ strlen(t)-i-1 ] )
			return 0;
	return 1; }

main(){
	printf("%d\n", palindrom("palindrom"));
	printf("%d\n", palindrom("atoidiota")); }
0
Krycho napisał(a)

To mnie nie powinni przepuszczac chyba na drugi rok i stawiac 5 z matmy.

Z tym polemizować nie sposób, pełna racja.

Tylko co to jest ta "matma"? Ja miałem na pierwszym roku 5 oddzielnych przedmiotów, teraz to w jeden połączyli?

Nie licze silnii rekurencyjnie tylko zlozonosc jest liniowa.

Mam rozumieć, że liczenie silni rekurencyjnie daje złożoność nieliniową?

To ze nie pamietam rozwiniecia tej funkcji to taki blad?

A po co pamiętać jakieś rozwinięcie? :|

Powtorze jeszcze jedna rzecz, ze o optymalizacji moge myslec przy duzych projektach, nie przy malych programikach, gdzie to czy sie wykona w 20ms czy 5ms, czy nawet 200ms nie zrobi mi zadnej roznicy, bo i tak tego nie zauwaze.

To jest bardzo złe podejście. Trochę na poziomie niektórych robotników drogowych, którzy mówią "to jest mała dziura, więc zalejemy ją błotem, a nie asfaltem".
Każdy program od początku do końca należy pisać solidnie, dzieląc na funkcje, nie powielając tego samego kodu, i starając się upraszczać wszelkie operacje, zwłaszcza obliczeniowe.
Do policzenia symbol Newtona obliczyłbyś trzy silnie, bo tak jest we wzorze? Absurd.

Jedyne co widze patrzac na sume xn/n! to x0/0! + x1/1! + x2/2! + ... + x^n/n!. No ale niestety tak mnie nauczyli to rozwijac ;((.

A to myśleć nie potrafisz, wiesz tylko to, czego wykułeś? :|

Tak wiec po prostu w zaleznosci od sytuacji moge sobie pozwolic na pewne nazwijmy to ulatwienia z mojej strony.

Spójrz na kod swój i bogdansa, serio chcesz się upierać przy tym, że Twój jest łatwiejszy?

// edit: poprawiłem nick autora kodu, o który mi chodziło

0

To ze kod jest krotszy nie znaczy ze jest prostszy. Matma jest podzielona na 1 roku na jak dobrze pamietam 4 przedmioty(czesci).

Przez tamto zdanie masz rozumiec ze nie musze odkladac na stos w przypadku duzych wartosci nie wiadomo ilu wartosci przejsciowych w celu policzenia silni z np 20, a potem ich sciagac, co samo w sobie jest czasochlonne. Wtracenie o liniowosci to tylko tak sobie.

Dla mnie to jest dobre podejscie, bo ja dostaje program do napisania i skupiam sie na tym aby spelnic dane kreteria, a potem jesli mam czas i ochote moge myslec o optymalizacji. Zadnego z prowadzacych nie obchodzilo nigdy czy moj program wykonuje sie 5ms czy 200ms, bo dla nich to bylo niezauwazalne, a raczej patrzyli na to czy liczone wartosci sa poprawne, czy sie nie crashuje, czy dziala zgodnie z zalozeniami. Tak wiec sry, programy optymalne to ja sobie pisze ale na spoju, gdzie sa okreslone ramy czasowe, w ktorych wykonywany kod musi sie zmiescic.

Nie nie potrafie myslec, klepie pusto kod i starczy mi to... To ze dostaje za to zazwyczaj 5 mi odpowiada i nie bede tego zmienial.

0
Krycho napisał(a)

To ze kod jest krotszy nie znaczy ze jest prostszy.

Ogólnie nie, ale w tym przypadku właśnie tak jest..

Zadnego z prowadzacych nie obchodzilo nigdy czy moj program wykonuje sie 5ms czy 200ms, bo dla nich to bylo niezauwazalne, a raczej patrzyli na to czy liczone wartosci sa poprawne, czy sie nie crashuje, czy dziala zgodnie z zalozeniami.

No cóż, to akurat źle świadczy o Twoich prowadzących.
Ja za takie coś postawiłbym 3 (gdybym oczywiście zajmował się wystawianiem ocen), bo niby zwraca poprawny wynik, ale poza tym jest słabe.

Tak wiec sry, programy optymalne to ja sobie pisze ale na spoju, gdzie sa okreslone ramy czasowe, w ktorych wykonywany kod musi sie zmiescic.

No cóż, ja mam takie podejście, że zawsze piszę taki sam kod. Nie mam czasu na rozmyślanie - to do szkoły, więc słabo, to dla mnie, więc optymalnie, to dla klienta, więc się zepsuć za dwa lata, żebym mógł zarobić na poprawce... To zawsze jest mój kod, więc ma być napisany jak najlepiej.

Tak sobie myślę, że może prowadzący zajęcia powinni ustalać limity na czas wykonania programu, żeby od początku uczyć studentów rozsądnego podejścia do pisania programów.

Nie nie potrafie myslec, klepie pusto kod i starczy mi to... To ze dostaje za to zazwyczaj 5 mi odpowiada i nie bede tego zmienial.

Podejrzewam, że z takim podejściem trudno będzie Ci się przyzwyczaić do braku ocen. A te skończą się za parę lat. W pracy nikt ich nie stawia, za to ważny jest sensowny kod, jeśli nie będziesz takiego pisał, to ciągle będziesz opieprzany.

Napisałeś więcej kodu, który jest w dodatku mniej wydajny. Na tym nie polega dobre programowanie.

0

Prawda jest ze nie zawsze Od razu wpadnie sie na pomysl wydajniejszego algorytmu. Dlatego mamy obiektowosc zeby potem bez konsekwencji i zmian w interfejsie moc sobie zmienic po prostu sam algorytm. Na dobra sprawe piszac klientowi program oddaje sie mu gotowy program. Jesli spelnia on jego wymogi to nie ma zadnych problemow. Raczej zadna osoba nie naklada na swoj program ram czasowych wykonywania, dopoki dziala to plynnie dla oka, to nie obchodzi go czy wykona sie to w pare czy pareset milisekund. Tak wiec spoko niech opieprzaja...

1

Prawda jest ze nie zawsze Od razu wpadnie sie na pomysl wydajniejszego algorytmu.

Zgoda, nie zaczynamy od szukania najbardziej wydajnego algorytmu. Zazwyczaj nie ma też żadnego znaczenia kilkuprocentowy wzrost szybkości. Ale przed rozpoczęciem kodowania, należy się zastanowić czy wymyślony algorytm nie jest jednym z gorszych. Dostajesz polecenie: napisz funkcję, która szuka w uporządkowanej tablicy tab liczby x, wpada Ci do głowy przeszukiwanie liniowe, implementujesz.
Działa? działa.
Czas wykonania dla tablicy mającej kilkaset milionów elementów, około 0,2 ms.
Doskonały algorytm, niczego mi więcej nie trzeba.
Takie jest Twoje podejście, mam nadzieję, że widzisz, iż jest ono durne.

0

Nie moje podejscie jest takie ze jesli tablica jest uporzadkowana to przeszukuje metoda bisekcji, jesli nie sortuje np. quick sortem i wtedy bisekcja szukam elementu. Problemy czysto programistyczne to inna sprawa, jesli dochodzi matma to juz nie mam ochoty sie zastanawiac nad skroceniem sobie wzorow.

2

Nie zrozumiałeś. Twoje podejście jest takie: Jak znajdę algorytm, który działa i na przykładowych danych ma akceptowalny czas wykonania, to się nie zastanawiam nad istnieniem lepszego algorytmu. Wg mnie, gdybyś wymyślił szukanie liniowe i nie słyszał wcześniej o szukaniu binarnym, to by Cię liniowe zadowoliło (działa, czas jednego szukania jest akceptowalny).
Btw, podejście, że najpierw sortuję a potem szukam binarnie wcale nie jest oczywiste. A w pewnych przypadkach jest nawet głupie.

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