Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akci až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 10 - Výpočet libovolné mocniny

V minulé lekci, Největší společný dělitel (Euklidův algoritmus), jsme si ukázali Euklidův algoritmus, který najde největšího společného dělitele dvou čísel.

Algoritmus výpočtu n-té mocniny je velmi jednoduchý, avšak je zapotřebí si uvědomit, že exponent mocniny může být i záporný nebo nulový. Základ mocniny budeme považovat za argument a a exponent za argument b.

Mocnina

Výpočet mocniny s kladným exponentem

Začneme s výpočtem mocniny s kladným exponentem. Budeme vycházet z podstaty mocniny, tedy z toho, že 23 = 2 * 2 * 2. Jinými slovy, je třeba argument a vynásobit b - 1 krát argumentem a:

  • a = 2
  • b = 3
  • b - 1 = 2
  • hodnotu a je třeba vynásobit 2x hodnotou a (a * a * a)
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Nyní není nic jednoduššího než použít cyklus for běžící od b do 2 (ne do jedna, protože potřebujeme o jedno násobení méně). Kód funkce mocnenikladnym(a,b) se nachází níže.

Výpočet libovolné mocniny

Zde je třeba rozložit funkci na 3 podmínky:

  1. b > 0 - vypočítáme klasickou mocninu s kladným exponentem (např. 23)
  2. b < 0 - výsledek je převrácená hodnota takové mocniny, kde je argument b kladný (např. 2−3 = 1 / 23). K získání kladného exponentu použijeme jeho absolutní hodnotu.
  3. b = 0 - výsledek je vždy 1 (např. 20 = 1)

Funkce na výpočet libovolné mocniny: mocneni(a,b).

Aplikace - zdrojový kód

Funkce mocneni() vrátí argument a umocněný na argument b. Funkce zavolaná tímto způsobem: mocneni(2,3) vrátí 23, což je 8.

  • /**
     * Vrati 'a' umocnene na 'b'. Pokud je 'b' kladne.
     */
    static int mocnenikladnym(int a, int b) {
        int c = a;
        for (; b > 1; b--) {
            c = c * a;
        }
        return c;
    }
    
    /**
     * Vrati 'a' umocnene na 'b'.
     */
    static int mocneni(int a, int b) {
        if (b > 0) {
            return mocnenikladnym(a, b);
        }
    
        if (b < 0) {
            return (1 / mocnenikladnym(a, Math.abs(b)));
        }
    
        return 1;
    }

V další lekci, Výpočet řešení kvadratické rovnice, si ukážeme algoritmus pro výpočet řešení kvadratické rovnice včetně zdrojového kódu a vývojového diagramu.


 

Předchozí článek
Největší společný dělitel (Euklidův algoritmus)
Všechny články v sekci
Matematické algoritmy
Přeskočit článek
(nedoporučujeme)
Výpočet řešení kvadratické rovnice
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
13 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, sushi a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity

 

 

Komentáře
Zobrazit starší komentáře (6)

Avatar
Lukaaash
Tvůrce
Avatar
Lukaaash:1.5.2013 21:17

Fajn, tak díky za vysvětlení.

Odpovědět
1.5.2013 21:17
Trocha poezie do toho umírání
Avatar
Tomáš
Neregistrovaný
Avatar
Tomáš:14.1.2014 21:57

Ahoj nemáš algoritmus na vypocet prirozeneho logaritmu pomoci taylora? Kdyby ani byl bych ti moc vděčný :)) Děkuju

 
Odpovědět
14.1.2014 21:57
Avatar
Tomáš
Neregistrovaný
Avatar
Tomáš:14.1.2014 21:57

Ahoj nemáš algoritmus na vypocet prirozeneho logaritmu pomoci taylora? Kdyby ani byl bych ti moc vděčný :)) Děkuju

 
Odpovědět
14.1.2014 21:57
Avatar
Kit
Tvůrce
Avatar
Odpovědět
14.1.2014 22:01
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Tomáš
Neregistrovaný
Avatar
Odpovídá na Kit
Tomáš:14.1.2014 22:08

Myslel jsem kod programu, ktery by to dokazal počítat, na tenhle odkaz jsem se díval a navíc to nesedí na cely definicni obor..

 
Odpovědět
14.1.2014 22:08
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
coells
Tvůrce
Avatar
Odpovídá na Tomáš
coells:15.1.2014 0:01

Jiste, ze to sedi na cely definicni obor, staci pouzivat vety o logaritmech.

#import <Foundation/Foundation.h>

double ln(double x, int steps)
{
    if (x == 0)
        return -1.0 / 0.0;
    if (x < 0)
        return 0.0 / 0.0;

    double t = x;
    double multiplier = 0.0;
    double ln_10 = 2.302585092994046;

    while (t >= 1.0) t /= 10.0, multiplier++;
    while (t < 0.1) t *= 10.0, multiplier--;

    double taylor = 0.0;
    double y = 1.0;
    double sgn = 1.0;

    for (double i = 1.0; i <= steps; i++)
    {
        y *= t - 1.0;
        taylor += sgn * y / i;
        sgn = -sgn;
    }

    return taylor + ln_10 * multiplier;
}

int main(int argc, const char * argv[])
{
    const int steps = 10000;

    double ln_0 = ln(0, steps);
    double ln_1 = ln(-1, steps);

    double x = 28394;
    double ln_x = ln(x, steps);
    double exact_x = log(x);

    NSLog(@"ln(0)=%f\nln(-1)=%f\nln(x)=%f\nlibrary log(x)=%f\n", ln_0, ln_1, ln_x, exact_x);

    return 0;
}
 
Odpovědět
15.1.2014 0:01
Avatar
fanda
Člen
Avatar
fanda:17.8.2015 15:53

Ahoj, zkusím doplnit alternativní způsob výpočtu mocniny

/// <summary>
/// Výpočet mocniny s časovou náročností ln(N) a paměťovou 1.
/// </summary>
/// <param name="a">základ</param>
/// <param name="b">exponent</param>
/// <returns>Vrací a umocněno na b.</returns>
public static double Pow(double a, int b)
{
        // Povinné ošetření mezních situací
        if (b == 0) return 1;
        if (b < 0)  return 1 / Pow(a, -b);

        // Výpočet:
        //      Pow = a ** b
        // je převeden na:
        //      Pow = (a ** b) * c;
        //   kde c = 1.
        double c = 1;
        while (b > 1)
        {
                // Před úpravou argumentů platí: Pow = (a ** b) * c
                c *= (b & 1) == 1 ? a : 1;
                a *= a;
                b >>= 1;
                // Po úpravě argumentů stále platí: Pow = (a ** b) * c,
                // ale b je poloviční.
        }

        // Stále platí:
        //    Pow = (a ** b) * c;
        // ale b == 1, takže vzorec je možné zjednodušit na:
        //    Pow = (a ** 1) * c = a * c
        return a * c;
}
 
Odpovědět
17.8.2015 15:53
Avatar
David Hynek
Tvůrce
Avatar
David Hynek:17.8.2015 18:33

Taylorův polynom... celkem by mě to zajímalo. Dokážete jej polopaticky vysvětlit? Já s ním mám celkem problém...

Odpovědět
17.8.2015 18:33
Čím víc vím, tím víc věcí nevím.
Avatar
 
Odpovědět
17.8.2015 18:56
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na David Hynek
Jan Vargovský:17.8.2015 19:02

Máš funkci a tu nahradíš polynomem n-tého řádu v nějakém bodě x. Čím je řád n vyšší, tím je okolí x čím dál tím přesnější. Tohle je takový začátek co to zhruba je.

 
Odpovědět
17.8.2015 19:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 16. Zobrazit vše