Jak zastąpić komendę?

Jak zastąpić komendę?
RS
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Lokalizacja:Gliwice
  • Postów:7
0

Witam,
Krótki opis sytuacji.
Do wykonania mam zadanie :
Zdefiniuj funkcję parametrów x i n, wyznaczającą iteracyjnie wartość:
f1(x,n) = 1/x + 1/ x2 + 1/ x 3+ 1/ x4 + . . . + 1/ x n ;
W funkcji main wielokrotnie wczytuj argumenty x i n, a następnie obliczaj i prezentuj
wartość funkcji, aż do momentu podania x == 0 lub n <= 0.

Mój kod wygląda tak :

Kopiuj
#include <stdio.h>
#include <math.h>

double funkcja (double, double);

int main()
{
	double wynik, x, n;
	
	while(1)
	{
	printf("Podaj wartosc x oraz n :");
	scanf("%lf%lf", &x, &n);

	if(x == 0)
		break; 

	if(n<=0)
		break;

	wynik = funkcja ( x, n ) ;

	printf(" Wartosc funkcji to : %.3lf \n", wynik);
	}
	
}
double funkcja( double x, double n )
{
	int i;
	double f = 0; 

	for( i = 1; i <= n; i++ )
		{
			f += 1 / pow(x, i); 
		}

	return f; 
}

Pytanie brzmi : W jaki sposób można zastąpić komendę " pow " ?
Z góry dziękuję i pozdrawiam

edytowany 4x, ostatnio: RybaSG
Gynvael Coldwind
  • Rejestracja:ponad 21 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Zurich, Switzerland
  • Postów:457
3

Mnożeniem :)
Zacznij od jakiegoś double p = x; a potem co iteracje pętli rób p *= x;.

Gdyby nie były to potęgi z kolejnymi, naturalnymi wykładnikami, tylko np. wykładnik byłby liczbą rzeczywistą, to musiałbyś zaimplementować jakiś ciekawszy numerycznie algorytm.


peace,
gynvael.coldwind//vx "Imagination is more important than knowledge..." Albert Einstein
RS
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Lokalizacja:Gliwice
  • Postów:7
0

Ok, dzięki :)

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 dni
3
  1. Zapoznaj się z inkrementacją, bo jej nie rozumiesz: http://4programmers.net/Forum/1101404
  2. Używaj wyłącznie angielskiego nazewnictwa: http://4programmers.net/Forum/1208091
  3. Do liczników wszelkiego rodzaju użycie double - to sabotaż własnej pracy
  4. Wg mnie lepiej jakoś tak:
Kopiuj
#include <stdio.h>
#include <math.h>
 
double func(double x,unsigned count)
  {
   double sum=0,add;
   for(add=1/x;count--;add/=x) sum+=add;
   return sum;
  }
 
int main()
  {
   double x;
   unsigned count;
 
   while(1)
     {
      printf("Podaj wartosc x oraz n: ");
      if(scanf("%lf%u",&x,&count)==2)
        {
         if((!x)||(!y)) return 0;
         printf("Wartosc funkcji to : %.3lf\n",func(x,count));
        }
      else printf("Trzeba podać liczby\n");
      while(getchar()!='\n') {}
     }
  }

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
ŁF
A propos inkrementacji, na którą tak bardzo zwracasz uwagę, a która zwykle jest tak bardzo nieistotna (vide http://c2.com/cgi/wiki?PrematureOptimization) - co robi u Ciebie count--? Że nie wspomnę o formatowaniu równie unikalnym jak nieczytelnym (kiedyś o tym dyskutowaliśmy, ale nie mogę na to patrzeć).
_13th_Dragon
Zacznijmy od formatowania, już odpowiadałem ale ... dla początkującego każde formatowanie mało czytelne, dla mnie każde formatowanie o ile spójne jest czytelne (ale to najlepsze) z powyższego wynika jedno z dwóch - albo się plasujesz gdzieś pomiędzy mną a początkującym, albo to "moje" jest dla ciebie nieczytelne tylko przez brak obeznania się z nim (owszem mogą być obie przyczyny naraz).
_13th_Dragon
Co do PrematureOptimization, to mylisz przedwczesną optymalizacje z sensownym pisaniem kodu, czemu nie używasz zmiennych globalnych? O czyżby przedwczesną optymalizacja? Bo jak się pojawią problemy ze zmienną globalną to dopiero wtedy się poprawi. Co do count-- to tu akurat jest potrzebne, aby nie tworzyć dodatkowej zmiennej, oraz nie dzielić tego na dwie instrukcje. Czyli jeżeli użyłem przyrostkową to jest ona niezbędna, natomiast jak ty użyłeś przyrostkową to trzeba się zastanowić od czapy to zrobiłeś czy z rozmysłem - czyli wracamy do czytelności.
ŁF
Ewentualnie Ty plasujesz się między mną a początkującym ;-) Niektóre formatowania pomimo spójności są nieczytelne, rozumiem że to kwestia gustu i przyzwyczajenia, ale Twoje jest wybitnie nie w moim guście. Musisz się nieźle pocić w każdym nowym środowisku nad konfiguracją automatycznego formatowania. ktoś kiedyś w pracy robił review Twojego kodu?
ŁF
Ad premature optimization - to do mnie? Jakie zmienne globalne? oO
_13th_Dragon
"Ewentualnie Ty plasujesz się między mną a początkującym ..." - nie, bo dla mnie twoje formatowanie też czytelne. Ja wymagam aby współpracownicy właśnie tak formatowali kod.
_13th_Dragon
Dla mnie nieuzasadnione i++ jest nieco mniejszym złem niż zmienne globalne ale jednak. Więc jeżeli bezmyślne użycie i++ usprawiedliwiamy za pomocą premature optimization to dokładnie tak samo możemy usprawiedliwić zmienne globalne.
ŁF
Ale o co Ci chodzi z tymi zmiennymi globalnymi? Premature optimization zrozumiałeś na opak: jest to używanie ++i tam, gdzie równie dobrze można użyć i++ (różnica w wydajności jest symboliczna). Co do count-- będącej powodem tej wymiany komentarzy to masz w 100% rację, tu akurat jest niezbędna, żeby w dobrym momencie zakończyć pętlę, nie zwróciłem na to uwagi :-) Jeśli zaś chodzi o czytelność kodu, to dobrze ponazywane dodatkowe zmienne nigdy nie zaszkodzą.
ŁF
Tak samo jak nie zaszkodzą dodatkowe spacje (po średnikach, przecinkach, przed i po operatorach itp). A wracając do formatowania kodu - nigdy nigdzie nie spotkałem się z takim stylem, jakiego używasz Ty. Jeśli ja używam ogólnie przyjętego formatowania, to jestem zrozumiały dla wszystkich, jeśli Ty wymyślasz swoje formatowanie, to jesteś czytelny tylko dla siebie. To, że Ty uważasz za czytelne moje standardowe formatowanie i swoje unikalne, a ja tylko moje standardowe (i każde inne nie odbiegające od standardów) nie świadczy o umiejętnościach.
_13th_Dragon
"... różnica w wydajności jest symboliczna ..." - czyli też nie rozumiesz, przeczytaj to co pod linkiem. "Co do count-- ... tu akurat jest niezbędna ... nie zwróciłem na to uwagi" - no widzisz, właśnie o tym mówię, gdyby to był twój kod to po jakimś czasie nie wiedziałbyś jest niezbędna czy nie - trzeba byłoby za każdym razem od nowa "zauważyć". Więcej zmiennych = więcej kodu = więcej błędów, ponieważ ilość błędów wprost proporcjonalna ilości kodu (dla tego samego programisty).
ŁF
Moim zdaniem sztuką jest pisanie w taki sposób, żeby kod był czytelny i zrozumiały dla wszystkich, a nie dla wybranych. Kod pisze się raz, a czyta wielokrotnie, więc warto poświęcić czas, żeby był maksymalnie łatwy do zrozumienia. Z tego powodu niekonsekwencje (raz dwie spacje, raz jedna - nijak nie konwertujące się do często używanego taba) i oszczędzanie białych znaków (for(add=1/x;count--;add/=x) sum+=add; vs for (add = 1/x; count--; add /= x) sum += add;) uważam za nieczytelne.
_13th_Dragon
Na temat dodatkowych spacji też już niejednokrotnie mówiłem - na kiepski wzrok polecam lepsze okulary lub/oraz większy monitor. Co do formatowania, moja grupa pisze w tym formatowaniu i nie jesteśmy zainteresowani aby byliśmy czytelni dla innych kosztem czytelności dla nas. Większość środowisk bez problemu da się przestawić na takie formatowanie którego używam. Skoro fakt że dla ciebie większość formatowań dla ciebie czytelna - "nie świadczy o umiejętnościach" - (jak twierdzisz), to nie świadczy to również że masz większe umiejętności od początkującego, a jednak powinno.
ŁF
Czego nie rozumiem? Że jeśli kod w środku pętli zajmuje większość czasu iteracji pętli, to optymalizacja inkrementacji licznika jest tym, co określa się jako premature optimization? Jestem daleki od twierdzenia, że preinkrementacja jest zła; za zło uważam wytykanie błędów w miejscach, gdzie ich nie ma, a w użyciu postinkrementacji zwykle nie ma. Nawet w przypadku kodu z Twojego posta samo dzielenie i suma zmiennoprzecinkowa zajmie tyle czasu, że różnica między pre- czy postinkrementacją nie będzie mieć istotnego wpływu na czas wykonania pętli.
_13th_Dragon
"... Moim zdaniem sztuką jest pisanie w taki sposób, żeby kod był czytelny i zrozumiały dla wszystkich ..." - żaden z twoich kodów nie jest zrozumiały dla początkującego (no chyba że jakiś fragment) - więc może jednak nie dla wszystkich? Za nic nie zrobisz kod czytelnym dla "pani z księgowości" - więc może jednak nie dla wszystkich? Po tygodniu programiści bez problemów przestawiają się na omawiany styl, po czym już każdy uważa go za czytelniejszy.
_13th_Dragon
Nie rozumiesz punktów 2, 3 i 4.
ŁF
Ad &quot;Co do count-- ... tu akurat jest niezbędna ... nie zwróciłem na to uwagi&quot; - no widzisz, właśnie o tym mówię, gdyby to był twój kod to po jakimś czasie nie wiedziałbyś jest niezbędna czy nie - sam sobie nogę podstawiasz. Przecież to Twój kod i to on jest nieczytelny, bo ktoś czytając go pomylił się. Ja bym to rozbił na osobne, dobrze nazwane zmienne, żeby nie można było się pomylić, albo zapisał to w inny sposób (dekrementacja w ciele pętli). Czy jestem początkujący czy nie to akurat nie ma znaczenia, bo kod ma być zrozumiały dla wszystkich.
_13th_Dragon
Ta, zrozumiałem, lepsza nazwa niż count oraz dodatkowe zmienne oraz w związku z tym kilka wierszy więcej oraz w kolejnej wersji ktoś czegoś nie zauważył i błąd na który stracisz czas. Czytelność oznacza mały czas czytania kodu przez twoją grupę a nie ilość początkujących którzy są w stanie go przeczytać. Jak już pisałem - nie dasz rady napisać czytelny dla wszystkich - więc pisz czytelny dla swojej grupy.
ŁF
Nieuważnie cytujesz, co sugeruje, że nieuważnie czytasz. Nie napisałem że "że większość formatowań dla mnie czytelna", tylko że czytelne są dla mnie formatowania zgodne z ogólnie przyjętymi standardami. "Nie świadczy to również że masz większe umiejętności od początkującego, a jednak powinno" - nie rozumiem o co Ci tutaj chodzi, poza tym jeśli coś "powinno", to warto by to uzasadnić. Wracając do tematu - piszecie w swoim gronie, więc ma być czytelne dla was; a co z kosztem wdrożenia nowych osób?
ŁF
Moja księgowa nie zagląda do kodu (chociaż kto ją tam wie; w każdym razie nie chwali się, że to robi. Co do nooba - owszem, da się kod tak napisać, żeby uniknąć robienia kilku rzeczy w jednej linijce, kilku funkcjonalności w jednej metodzie i klasie, dobrze ponazywać wszystkie zmienne, stałe, metody, klasy, struktury itp., dobrze pogrupować kod pustymi linijkami - i wtedy będzie mu znacznie łatwiej, nawet jeśli sam nie będzie potrafił napisać tak przejrzystego kodu.
fasadin
dodam tylko jedno od siebie. oraz w kolejnej wersji ktoś czegoś nie zauważył i błąd na który stracisz czas Od tego sa unit testy.
_13th_Dragon
@ŁF, jeżeli "formatowania zgodne z ogólnie przyjętymi standardami" - rozumiesz domyślne formatowanie ustawiane przez większość środowisk to będzie to również "większość formatowań", jeżeli zaś pod tym rozumiesz podtrzymywanie formatowania przez istniejące środowiska - to coś kręcisz, ponieważ to co ja używam również jest podtrzymywanie - więc uważnie czytam a i w trakcie robię wnioski. @fasadin, no własnie o tym mówię, test pokazał że teraz źle i teraz co? cofamy zmiany i robimy na nowo? albo porównujemy znak po znaku wersje? albo szukamy w nowym kodzie błędu debugerem?
RS
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Lokalizacja:Gliwice
  • Postów:7
0

Czemu przy licznikach double jest złe?

Sopelek
for(float f = 0.0f; f < 20000000.0f; f+=1.0f) ile razy wywoła się ta pętla?
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 dni
0
RybaSG napisał(a):

Czemu przy licznikach double jest złe?
Temu: http://ideone.com/9Y579a


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Gynvael Coldwind
  • Rejestracja:ponad 21 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Zurich, Switzerland
  • Postów:457
7

@RybaSG
To ja przewrotnie napiszę, że akurat w przykładzie który miałeś, dla naturalnych n poniżej 252-1 (give or take) i tak by wszystko działało (związane z wyliczaniem w pętli ofc; przy czym precyzja i by się skończyła trochę szybciej), niemniej jednak warto zapoznać się z tym jak floaty działają od wewnątrz :)
@Sopelek rzucił kontr-przykład, w którym akurat liczba przy liczniku nie jest poprawnie reprezentowana we floatach (do 223-1 by było dobrze, ale 20000000.0f jest w okolicy 2**25 ;)

@_13th_Dragon
W ramach czepiania się szczegółów (co tak lubimy na forum uprawiać), Twój przykład nie pokazuje, że użycie double do licznika i jest niepoprawne - wszystkie liczby od 0 do 999 są poprawnie reprezentowane w double bez straty precyzji, i dodawanie +1 do nich również nie powoduje straty w precyzji.
Problem braku precyzji leży natomiast (jak pewnie wiesz) w tym jak obliczane jest A i B (0.1 nie można wyrazić bez straty precyzji w double).


peace,
gynvael.coldwind//vx "Imagination is more important than knowledge..." Albert Einstein
edytowany 4x, ostatnio: Gynvael Coldwind
ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 13 godzin
3
_13th_Dragon napisał(a):
RybaSG napisał(a):

Czemu przy licznikach double jest złe?
Temu: http://ideone.com/9Y579a

Tak jak GC napisał, pokazałeś że stukrotne dodanie do siebie 0.1 nie da dokładnie 100. Błąd będzie identyczny dla użycia double i dla użycia int jako licznika.
Jednak jest uzasadnienie dla nieużywania double w licznikach: wydajność. Jeśli co iterację zmienna zwiększana jest o liczbę naturalną, to nie ma żadnego uzasadnienia dla używania jako typu tej zmiennej czegoś innego niż typ naturalny/całkowity. Co prawda w praktyce spadek wydajności będzie zwykle pomijalny, ale użycie takiej konstrukcji to programistyczne faux pas, takie pierdnięcie przy stole, nikt nie umrze, ale wszyscy się skrzywią.


Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.