Potęgowanie liczby - zaoszczędzenie pamięci

Potęgowanie liczby - zaoszczędzenie pamięci
Tytanowyy
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:86
0

Witam, mam do Was pytanie, którą z operacji lepiej wykonać, mając parzystą potęgę, podnieść liczbę (a2)k czy (ak)2 Dzięki pozdrawiam

edytowany 3x, ostatnio: Tytanowyy
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 7 godzin
1

już pomijając kwestię formatowania, to i tak nie rozumiem, o co ci chodzi w podnieść liczbę a^2k do (a^2)^k czy też (a^k)^2

Co do czego chcesz podnosić?

Tytanowyy
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:86
0

Wybacz, korzystam z telefonu w tym momencie. Liczba a to liczba naturalna, którą chcę podnieść do parzystej potęgi 2k. I teraz mam pytanie, czy lepiej jest to zrobić w taki sposób: (a2)k czy (ak)2

Skąd takie pytanie, otóż w książce przeczytałem, że lepiej jest wykorzystać taki sposób niż 30 razy mnożyć liczbę, bo zaoszczędza się trochę pamięci - wydaje mi się to oczywiste, natomiast pytam się, bo może jest jeszcze jakaś róźnica przy mnożeniu potęgi

edytowany 11x, ostatnio: Tytanowyy
_13th_Dragon
O jakie liczby chodzi, bo jak o normalne mieszczące się w double to oba sposoby są równoznaczne i oba gorsze niż da się zrobić?
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
1

Zdecydowanie najlepiej a(2*k)


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
Lukasz_
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:140
1

W obu przypadkach wykonasz k+1 mnożeń więc nie ma różnicy. @_13th_Dragon Dlaczego według Ciebie najlepiej a^2k ?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Bo potęgowanie jest bardziej kosztowne od mnożenia.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Lukasz_
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:140
0

Przecież potęgowanie to właśnie mnożenie.

bogdans
To policz 2^(0.5) mnożąc.
Lukasz_
No dobrze, ale tu akurat możemy dojść aż do poziomu mnożeń sprzętowych. Jeżeli jest ktoś w stanie powiedzieć mi dlaczego x<sup>2k jest lepsze niż x</sup>k * x^k to słucham.
Patryk27
@Lukasz_: ponieważ mając x^2k wykonujesz 2k mnożeń, w drugim przypadku 2k+1? Nie mówiąc o efekcie motyla.
Lukasz_
Zle, ja to tylko tak rozpisałem w komentarzu. Chodzi o to co wyżej, że lepiej najpierw podnieść do połowy potęgi a potem pomnożyć przez siebie.
Tytanowyy
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:86
0

Tak, chodzi o liczby mieszczące się w typie double. Pytam się, bo myślałem, że jest jakaś różnica jeszcze przy wykorzystywaniu tego sposobu.

A to ciekawe, bo właśnie w książce mam napisane, że najlepiej jest robić tym, o którym wspomniałem.

Czyli @_13th_Dragon sugerujesz, że najlepiej jest używać sposobu tego, który podałeś, tak?

Pytam tylko tak orientacyjnie, bo skoro w książce piszą o 'zaoszczędzaniu pamięci', to chciałbym wiedzieć, który sposób jest w rzeczywistości lepszy.

Dzięki za odpowiedzi!

edytowany 1x, ostatnio: Tytanowyy
Lukasz_
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:140
0

Też tak uważam, o ile kompilator nam czegoś nie uprości sam to mnożenie liczb 2k razy jest bardziej kosztowne niż mnożenie k+1. Ze ściśle matematycznego punktu widzenia.

_13th_Dragon
Jeżeli masz durnie zrealizowane potęgowanie to masz durne wnioski.
Lukasz_
Czyli jesteś za głupi żeby wytłumaczyć. Rozumiem, zdarza się. Ktoś inny ?
_13th_Dragon
Nie, to ty jesteś za głupi by zrozumieć że realizacja b^n jako seria n mnożeń to jest najgłupszy algorytm z możliwych
flowCRANE
Panowie, panować nad słownictwem! @Lukasz_ - chcesz pożegnać się na jakiś czas z dostępem do forum? @_13th_Dragon - przystopuj trochę;
OA
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 10 lat
  • Postów:95
2

Potęgowanie to można zrealizować za pomocą O(lg(2k)) mnożeń używając prostego algorytmu rekurencyjnych kwadratów. Można go opisać tak:

Kopiuj
a^0      = 1
a^(2k)   = let t = a^k in t*t
a^(2k+1) = let t = a^k in a*t*t
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
4

Jeżeli chodzi o liczby typu double to istnieje np w C/C++ funkcja double pow(double,double)
która przeważnie jest realizowana jako: double pow(double b,double p) { return exp(p*log(b)); }
w innych językach podobnie. Jak widać podwójne wykorzystanie pow da gorszy wynik.

Dla potęg które są liczbami całkowitymi ma sens zrobienia tego w następujący sposób:

Kopiuj
double pow(double b,unsigned p)
  {
   double ret;
   for(ret=1;p;b*=b,p>>=1) if(p&1) ret*=b;
   return ret;
  }

wynik dokładnie ten sam.

PS
Tak a propos, jeżeli chodzi o to drugie potęgowanie to najlepszym sposobem będzie:

Kopiuj
double x=pow(b*b,k);

ponieważ:
*

Kopiuj
double x=pow(b,k);
x*=x;
  • nieco gorzej się czyta;
Kopiuj
double x=pow(b,2*k);

będzie miał o dwa mnożenia oraz jedno przesunięcie i dwa warunki więcej.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
Lukasz_
Tak jest o wiele lepiej, i przynajmniej wartość merytoryczna dużo większa dla wszystkich. Zwracam honor ;)
OA
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 10 lat
  • Postów:95
2

Odnośnie sposobu @_13th_Dragon - warto opisać skąd on się bierze. Biorąc dowolną liczbę a i potęgę naturalną n zamieniamy potęgę n na system dwójkowy. Zatem:n = 1*b[0] + 2*b[1] + 4*b[2] + 8*b[3] + 16*b[4] + ... gdzie b[k] przyjmują wartości 0 lub 1 (są kolejnymi bitami liczby n). Chcemy policzyć a^n, czyli:a^(1*b[0] + 2*b[1] + 4*b[2] + 8*b[3] + ...) = a^(b[0]) * (a^2)^(b[1]) * (a^4)^(b[2]) * (a^8)^(b[3]) * ... Algorytm jest taki:

  1. Zaczynamy od ret = 1 (element neutralny mnożenia).
  2. Liczmy kolejne kwadraty: a, a^2, a^4, a^8, a^16, ...
  3. Jeżeli k-ty bit jest zapalony w liczbie n ((n >> k) & 1 != 0), to mnożymy ret przez a^(2^k) obliczone wcześniej.
edytowany 4x, ostatnio: Oak
_13th_Dragon
... gwoli ścisłości, to nie jest mój sposób.
OA
Pomijając szczegóły implementacji robisz dokładnie to co opisałem.
_13th_Dragon
To się zgadza, ale sam sposób był wymyślony raczej przed moim urodzeniem.
OA
W to nie wątpię. Sam kiedyś go wyprowadziłem bez większych problemów. :)
_13th_Dragon
No właśnie to napisałem: - "to nie jest mój sposób"
OA
Tak, ale na początku zrozumiałem to jako "nie opisałeś mojego sposobu".
Tytanowyy
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:86
0

Mam jeszcze jedno pytanie do Państwa, czy algorytm który wykorzystuje mnożenie do obliczenia potęgi będzie lepszym rozwiązaniem niż użycie rdzennej funkcji do obliczania potęgi? Pozdrawiam

Lukasz_
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:140
0

Rdzennej czyli z math ?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
1

To zależy, jak już wspomniał @bogdans nie policzysz 20.5 za pomocą mnożenia.
Wydaje mi się (tak naprawdę trzeba przeprowadzić badanie, a wynik będzie zależał od procesora) że przy k w granicach do 25 powinno być szybsze poprzez mnożenie.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Tytanowyy
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:86
0

No rzeczywiście, byłby problem, nawet o tym nie pomyślałem :). Jeszcze raz dzięki za odpowiedz i i pozdrawiam

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)