UMOCNĚNÍ
Část I - celočíselný exponent
PROBLÉM
Jak efektivně určit hodnotu X**Z, kde X je reálné číslo a Z je nezáporné celé číslo? Běžně používáme operaci umocnění s operátorem **. Algoritmus realizovaný funkcí POWER uvedl poprvé matematik al-Kashi v roce 1414.
IMPLEMENTACE
Jednotka: vnitřní funkce nebo vnější, ale pak bez procedure příkazu
Parametry: reálné X, nezáporné celé Z
Vrací: X**Z
POWER: procedure
parse arg X, Z; Pwr = 1
do forever
if Z // 2 then Pwr = Pwr * X
Z = Z % 2
if Z = 0 then return Pwr
X = X * X
end
|
PŘÍKLAD
[Regina] Provádění následujícího programu bude násilně ukončeno a na displeji se vypíše chybové hlášení:
Error 26 ... line 3: Invalid whole number. To je důsledek implementačního limitu pro velikost exponentu.
/* BERNOULLI computes e */
numeric digits 20; Z = 1E+9
X = 1 + 1 / Z
say "e =" FORMAT(X**Z,,8)
|
Ale program
/* BERNOULLI computes e */
numeric digits 20; Z = 1E+9
X = 1 + 1 / Z
say "e =" FORMAT(POWER(X,Z),,8)
exit
POWER: procedure
...
|
dokončí výpočet a zobrazí e = 2.71828183
Část II - reálný exponent
Funkce REPOWER vypočte obecnou mocninu pro zadaná reálná čísla X a Z.
IMPLEMENTACE
Jednotka: vnitřní funkce
Parametry: reálná čísla X a Z, přirozené číslo P - počet platných číslic v hodnotě výsledku, implicitně 9
Vazby: funkce EXP a LN
Vrací: X**Z nebo vypíše chybovou zprávu: REPOWER: Výsledek není definován
REPOWER: procedure
parse arg X, Z, P
if P = "" then P = 9; P = P + 4; numeric digits P
if DATATYPE(Z, "Whole_number")
then
if X = 0 & Z <= 0
then call ERROR "REPOWER: Výsledek není definován"
else return X ** Z
else
select
when X > 0 then return EXP(Z * LN(X, P), P)
when X = 0 & Z > 0 then return 0
otherwise
call ERROR "REPOWER: Výsledek není definován"
end
ERROR: say ARG(1); exit
|
SOUVISLOSTI
Literatura
Knuth D. E. Seminumerical Algorithms, vol. 2 of The Art of Computer Programming
Addison-Wesley, 1973