Skocz do zawartości

Algorytm potęgi na liczby zmiennoprzecinkowe (C++)


patry

Rekomendowane odpowiedzi

Witam, napisałem taki program w C++ obliczający potęgę, ale ten program dizała tylko na liczby całkowite.

Oto kod tego programu -

 

#include

using namespace std;

int potega (int podstawa, int wykladnik)

{

int pomoc = podstawa;

 

for (int i = 1; i

{

podstawa = podstawa * pomoc;

}

 

return podstawa;

}

int main()

{

int podstawa, wykladnik, wynik;

 

cout

cin >> podstawa;

 

cout

cin >> wykladnik;

 

wynik = potega (podstawa, wykladnik);

 

cout

}

 

I mam takie pytanie - jka napisać program (albo zmodyfikować ten, który podałem), żeby potęgował również liczby zmiennoprzecinkowe??

Odnośnik do komentarza
Udostępnij na innych stronach

  • Odpowiedzi 34
  • Created
  • Ostatniej odpowiedzi

Top Posters In This Topic

Już dawno w C nie siedziałem, ale spróbuj użyć po prostu innego typu zmiennej.

Tu masz rozwiązanie rekurencyjne, znacznie ładniejsze matematycznie :)

double power (double podstawa, int wykladnik) {
   if (wykladnik == 1)
        return podstawa
  else 
        return podstawa*power(podstawa, wykladnik-1);
}

 

Coś takiego powinno zaziałać.

Nie pamiętam jakie są w C typy zmiennych zmiennoprzecinkowych, napisałem tutaj double, ale jeśli takowych nie ma, to użyj innych.

 

Możnaby jeszcze uwzględnić wartośc równą jeden dla dowolnej podstawy przy wykłąniku równym 0.

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki piotrek, teraz kod wygląda tak:

 

#include

 

using namespace std;

 

double potega (double podstawa, int wykladnik) {

if (wykladnik == 1)

{

return podstawa;

}

else

return podstawa*potega(podstawa, wykladnik-1);

}

 

int main()

{

int wykladnik;

double podstawa, wynik;

 

cout

cin >> podstawa;

 

cout

cin >> wykladnik;

 

wynik = potega (podstawa, wykladnik);

 

cout

}

 

Ale niestety nie do końca o ot mi chodziło :/

Bo chodziło mi o to, żeby i podstawa i wykładnik były liczbami zmiennoprzecinkowymi.

Czy ktoś wie jak napisać na to program??

Odnośnik do komentarza
Udostępnij na innych stronach

Spróbuj wykładnik też zadeklarować jako double.

Nie wiem, czy komputer sobie z tym poradzi, po fukcja potęgowa o wykładniku wymiernym to funkcja pierwiastkowa, a o wykładniku niewymiernym to nawet nie wiem jak to wygląda.

Możesz spróbować. Najwyżej otrzymasz jakiś error.

 

A ta funkcja, co powyżej działa dobrze? Pytam z ciekawości ;)

Odnośnik do komentarza
Udostępnij na innych stronach

No miałeś kilka malutkich błędów które w minutkę poprawiłem no i działa wspaniale :)

 

Zdeklarowanie wykładnika jako double niestety nic nie da, bo sam napisałeś funkcje - double power (double podstawa, int wykladnik) {

if (wykladnik == 1)

return podstawa

else

return podstawa*power(podstawa, wykladnik-1);

}

I widać, że wykładnik zmniejsza się o 1 i tu jest problem :/

Odnośnik do komentarza
Udostępnij na innych stronach

Heh, no faktycznie, my bad :o

 

Po prostu w taki sposób działa funkcja potęgowa. Chyba nawet nie istnieje w klasycznej matematyce taki twór z wykładnikiem niewymiernym :)

 

No chyba jednak istnieje i jest to raczej pierwiastek :)

Może by tak napisać program obliczający pierwiastek?? Ale jak to zrobić??

Odnośnik do komentarza
Udostępnij na innych stronach

piotrek..... latwo powiedziec.... al ekomputer nei ma mozgu....

potegowanie to mnozenie wielokrotne, mnozenie to wielokrotne dodawanie....

ale pierwiastkowanie to jest odwrotnoscia potegowania.... tylko ze to nic nie daje w dalszym rozumowaniu :)

 

zreszta sami wiecie jak skomplikowane jest samo odejmowanie :P

Odnośnik do komentarza
Udostępnij na innych stronach

Raczej Newtona-Raphsona ;). Sprawa jest prosta, pobierasz liczbę, ustalasz dopuszczalny błąd (pewnie 0.01 wystarczy), następnie robisz pętle która się kończy w momencie gdy dwa kolejne obliczenia różnią się o mniej niż ustaliłeś za dopuszczalny błąd, sam wzór to: (poprzedni wynik + iloraz liczby przez poprzedni wynik) całość podzielona przez dwa :), a co podstawić na początek do pierwszego przeliczenia? Dowolną liczbę dodatnią :).

 

BTW. Po co wmieszaliście rekurencję do potęgowania? To nie najlepszy nawyk.

Odnośnik do komentarza
Udostępnij na innych stronach

Blade.. tu chodzi zeby samemu napisac taka funkcje przy uzyciu JEDYNEGO DZIALANIA :)

sqrt wykorzystuje funkcje zlozona procesora... konkrtnie to na wejsciu ejst cos.. a na wyjsciu po przemieleniu przez zestaw tranzystorow wlasnie do mulenia tylko i wylacznie sqrt wylatuje wynik... problem jest taki ze ma ograniczenie na uint to po pierwsze... a po drugie ma watpliwa wydajnosc i jeszcze bardziej watpliwa dokladnosc (jest ulepszona wersja tego ukladu wygenerowana konkurencj alosowa... ukald spisuje sie swietnie, robi co ma robic dobrze, szybko i z wieksza dokaldnoscia... tylko ze jest bez sensu... poki nei bedzie dokumentacji tecnicznej jak on dziala .... a nei wiadomo jak dziala.. to nei moze byc implementowany... bo neistety te procki sluz anie tylko do zabawy)

cala zabawa zeby funkcja dzialal na typach wiekszych od int

 

Gotham-bo mamy zly nawyk ze skzoly, bo jakis kretyn na koncu XIX wieku wpisal do programu nauczania rozklad na czynniki pierwsze przy szukania NWD (najwiekszy wspolny dzielnik) zamiast algorytmu Euklidesa.... a to wplywa na tok rozumowania..... zgadzam sie ze jak najbardziej nie po dordze :)

Odnośnik do komentarza
Udostępnij na innych stronach

Gotham - może i nie najlepszy, ale najładniejszy. Rekurencja ma swoje wady (tworzenie wielu kopii jeden funkcji), ale kod jest przejrzysty i czytelny. W tym prztypadku, imo, wyśmienicie się sprawdza.

 

BLADE - Sqrt to, o ile pamiętam, tylko pierwiastek kwadratowy.

Odnośnik do komentarza
Udostępnij na innych stronach

piotrek-tak, sqrt do tego sluzy... ale mozna go mu zmienic wykladnik na ujemny, a co do rekurencji to jest przeciez jeszcze mnozenie i poegowanie skrotowe, tez calkiem przejzyste, ale stosuje sie je do duzych i masowych obliczen... gdzie ilosc powtorzen moglaby popsuc dzien :)

Odnośnik do komentarza
Udostępnij na innych stronach

No ale w pliku math.h jest funkcja która oblicza potęgę i pierwiastek z liczb zmiennoprzecinkowych, więc ci którzy pisali ten plik jakoś wpadli na pomysł jak to napisać.

Więc powinno się dać napisać taki program...

Odnośnik do komentarza
Udostępnij na innych stronach

patry-pies jest w tym.... ze funkcja z math.h to funkcja dobra... ale ma ograniczenie do kilku zaledwie typow..... konkretnie jak wcisniesz tam jakas dajmy na to 4096 bitowa liczbe to ta biblioteka tego nie liczy :)

wogole to malo ktora biblioteka zawiera funkcje na lcizenie takich potworkow....

 

i dlatego dobrze ze ktos siedzi i robi doswiadczenia podstawowe z tego co juz wymyslono... bo inaczej nei mozna sie tego nauczyc jak tylko samemu budowac takie narzedzia :)

Odnośnik do komentarza
Udostępnij na innych stronach

piotrek... ja po prostu wesolo zakladam ze jak ktos bierze sie samemu za budowanie funkcji, ktore juz sa dosc dobre...to juz liznal teorie liczb i mu kryptografia po glowie lazi :) albo chociaz crash test kompa... czyli w jakim tempie zniesie jajo przy liczeniu takich rzeczy :)

Odnośnik do komentarza
Udostępnij na innych stronach

yy, jeśli są, to po co pytasz jak napisać? :)

 

No bo korzystanie z gotowców nie leży w mojej naturze :)

 

A serio - to uczę się programować w C++ i nie miałem pomysłu na napisanie innego programu :)

 

PS to da się napisac taki program, czy jest to raczej niemożliwe??

Odnośnik do komentarza
Udostępnij na innych stronach

hah, ale babol, co ja w ogóle napisałem, człowiek się prześpi i od razu lepiej myśli :o

 

Ale prawda jest taka, że nie mam pojęcia jak potęgować z wykładnikiem niewymiernym. Jedyny przychodzący mi do głowy sposób na takie obliczenia to zaokrąglenie do wymiernej i wyliczenie - wtedy tylko pierwiastkujesz podstawę o stopień mianownika, i wynik podnodsisz do potęgi o wykładniku licznika.

Na obliczanie pierwiastków wcześniej przedstawiono algorytm.

Odnośnik do komentarza
Udostępnij na innych stronach


A = count ( forum."Program languages".post.last_30days )
B = count ( forum."Program languages".post._this ) // istnieje niecałą dobe ;]
IMHO A - B

 

PARTY:jak chcesz się uczyć i stworzyć prosty pożyteczny program, to mogę Ci zasugerowac to czego mi brakuje w programach do postproducji:

 

"programowalne tryby nakładania warstw"

(szczegóły na http://www.moja.glowa.pelna.pomyslow.ok)

 

Najprawdopodobniej rewolucyjnej nowości już się nie odkryje, bo można kombinowac i mieszac tryby które sa dostępne, ale tryb Pin Light w Photoshopie pojawił sie dopiero w wersi 7 (chyba) . Być może są jeszcze nieznane efekty do odkrycia :)

Odnośnik do komentarza
Udostępnij na innych stronach

polecam algorytm Karaczuby, jest bardzo wydajny do liczenia poteg..... i swietnie sie sprawdza przy wywolaniach nierekurencyjnych... jest bardzo elegancki, choc prawdziwa moc wydajnosci z przewaga nad tradycyjnym sqrt uzyskuje dopiero powyej 3kbitowej liczby :)

moze ktos na normalna matme rozpisac w jaki sposob konkretnie chcecie to liczyc? sie pomysli i cos wymysli :)

 

w sumie gonre ma racje...... do poprawiania wydajnosci i psiania funkcji liczenia (i sprawdzeniaich porpawnosci) to trzeba miec sporo doswiadczenia, zeby wiedziec gdzie ktora metoda sie potyka...

lepiej bierzcie sie za cos gdzie bledy sa dopuszczalne, a sprawdzanie nei wymagane bo mzona to zrobic na oko :)

Odnośnik do komentarza
Udostępnij na innych stronach

Ale się na niego uwzięliście.

 

Chłopak chce się nauczyć, a wy odrazu mu renderer proponujecie (w sumie nienajgorszy pomysł :D) albo jakieś programowalne coś.

 

Wy na pewno od "Hello World" nie zaczynaliście. Pewnie na początek w celu zaznajomienia się z językiem programowania, zajmowaliście się AI :p

Odnośnik do komentarza
Udostępnij na innych stronach

Ehh... ale się rozpisaliście.

Mi tylko chodzi o to, żeby zmodyfikować ten kod:

 

#include

 

using namespace std;

 

double potega (double podstawa, int wykladnik)

{

double pomoc = podstawa;

 

for (int i = 1; i

{

podstawa = podstawa * pomoc;

}

 

return podstawa;

}

 

int main()

{

double podstawa, wynik;

int wykladnik;

 

cout

cin >> podstawa;

 

cout

cin >> wykladnik;

 

wynik = potega (podstawa, wykladnik);

 

cout

}

 

W taki sposób, żeby wykładnik był liczbą zmiennoprzecinkkową (ale nie niewymierną) i program poprawnie obliczył tą potęgę.

Więc da się to zrobić?? :D

Odnośnik do komentarza
Udostępnij na innych stronach

da sie :)

tylko ze olej w niej zmiennoprzecinkowosc

ustal sztywno zakres nad i pod przecinkiem.... i po prostu go calego nie wykorzystuj (zera niewazace won).... inaczej musialbys dopisac dynamiczny przydzial pamieci.. ktory zmienialby sie na biezaco :)

Odnośnik do komentarza
Udostępnij na innych stronach

Gość browar102

Oto jak wyglądałby kod źródłowy programu napisanego w C++ do obliczania pierwiastków dowolnego stopnia. Gdzies na necie znalazlem algorytm i napisalem program wiec nie pytajcie o co w nim chodzi bo tez bym chcial to wiedziec. Ważne że działa :D Pozdrawiam!

 

#include

#include

 

 

using namespace std;

 

int main()

{

int n,m,i;

double x,z,y,p,d;

cout

cin >> x;

cout

cin >> n;

cout

cin >> m;

 

y = 0;

p = 0;

d = 1;

 

if(x

cout

else

{

while(p!=x)

{

if(p>x)

{

y=y-d;

d=d/10;

if(m)

{

m=m-1;

y=y+d;

p=1;

i=0;

}

else

{break;}

}

else

{

y=y+d;

p=1;

i=0;

}

while(i

{

p=p*y;

i=i+1;

}

 

}

cout

}

getch();

}

Odnośnik do komentarza
Udostępnij na innych stronach

Hmm moze moj bedzie latwiejszy do zrozumienia, dodalem komentarze jak cos ;]

 

#include 
#include 


using namespace std;


int main()
{
int n; //stopien pierwiastka
short m; // ilosc miejsc po przecinku
double x; // liczba pierwiastkowana
double w; // zmienna do sprawdzania pierwiastka
double p; // zmienna p okreslajaca pierwiastek 
double z = 1; // zmienna do obliczania ilosci miejsc po przecinku podanej w m

   cout     cin >> x;
   cout     cin >> n;
   cout     cin >> m;

//ZAMIANA LICZBY M NA ILOSC MIEJSC PO PRZECINKU
   for(int i = 0; i     {
       z /= 10;
   }

p = 0;
w = 1;
//OBLICZANIE LICZBY 
   do
   {
           p+=z;   // dodanie do zmiennej wartosci
           w = 1; // wynik na poczatku rowny 1
       for(int i = 0; i        {
           w = w * p; // sprawdzanie pierwiastka 
       }
   }
   while(w     p-=z; // odejmij jedna wartosc(bo w 
   {
       cout     }
getch();
}

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się



×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Wykorzystujemy cookies. Przeczytaj więcej Polityka prywatności