Knuth's power tree
(Used for computing xn efficiently using Knuth's power tree.)
The requirements of this draft task are to compute and show the list of Knuth's power tree integers necessary for the computation of Xn for any real X and any non-negative integer n.
Then, using those integers, calculate and show the exact (not approximate) value of (at least) the integer powers below:
- 2n where n ranges from 0 ──► 17 (inclusive)
- 3191
- 1.181
- 2n where n ranges from 0 ──► 17 (inclusive)
A zero power is often handled separately as a special case.
Optionally, support negative integers (for the power).
An example of a small power tree for some low integers:
1 \ 2 ___________________________________________/ \ / \ 3 4 / \____________________________________ \ / \ \ 5 6 8 / \____________ / \ \ / \ / \ \ 7 10 9 12 16 / //\\ │ │ /\ / _____// \\________ │ │ / \ 14 / / \ \ │ │ / \ /│ \ 11 13 15 20 18 24 17 32 / │ \ │ /\ /\ │ /\ │ /\ │ / │ \ │ / \ / \ │ / \ │ / \ │ 19 21 28 22 23 26 25 30 40 27 36 48 33 34 64 │ /\ /│\ │ │ /\ │ /\ /│\ │ /\ /│\ │ │ /\ │ / \ / │ \ │ │ / \ │ / \ / │ \ │ / \ / │ \ │ │ / \ 38 35 42 29 31 56 44 46 39 52 50 45 60 41 43 80 54 37 72 49 51 96 66 68 65 128
Where, for the power 43, following the tree "downwards" from 1:
- (for 2) compute square of X, store X2
- (for 3) compute X * X2, store X3
- (for 5) compute X3 * X2, store X5
- (for 10) compute square of X5, store X10
- (for 20) compute square of X10, store X20
- (for 40) compute square of X20, store X40
- (for 43) compute X20 * X3 (result).
Note that for every even integer (in the power tree), one just squares the previous value.
For an odd integer, multiple the previous value with an appropriate odd power of X (which was previously calculated).
For the last multiplication in the above example, it would be (43-40), or 3.
According to Dr. Knuth (see below), computer tests have shown that this power tree gives optimum results for all of the n listed above in the graph.
For n ≤ 100,000, the power tree method:
- bests the factor method 88,803 times,
- ties 11,191 times,
- loses 6 times.
See: Donald E. Knuth's book: The Art of Computer Programming, Vol. 2, Second Edition, Seminumerical Algorithms, section 4.6.3: Evaluation of Powers.
See: link codegolf.stackexchange.com/questions/3177/knuths-power-tree It shows a Python computer program example.
See: link comeoncodeon.wordpress.com/tag/knuth/ (See the section on Knuth's Power Tree.) It shows a C++ computer program example.
REXX
This REXX version supports results up to 1,000 decimal digits (which can be expanded with the numeric digits nnn REXX statement. Also, negative powers are supported. <lang rexx>/*REXX program produces & shows a power tree for P, and calculates & shows X^P*/ numeric digits 1000 /*be able to handle some large numbers.*/ parse arg nums /*get set stuff: sets of three numbers.*/ if nums= then nums='2 -4 17 3 191 191 1.1 81' /*Not specified? Use defaults*/
/*X lowPow highPow ··· repeat*/ do until nums= parse var nums x pL pH nums; x=x/1 /*get X, lowP, highP; and normalize X. */ if pH= then pH=pL /*No highPower? Then assume lowPower. */
do e=pL to pH; p=abs(e)/1 /*use a range of powers; use │E│ */ $=powerTree(p); w=length(pH) /*construct the power tree, (pow list).*/ /* [↑] W≡length for show*/ do i=1 for words($); @.i=word($,i); end /*build a fast pow array.*/
if p==0 then do; z=1; call show; iterate; end /*handle case of 0 power.*/ !.=.; z=x; !.1=z; prv=z /*define the first power of X. */
do k=2 to words($); n=@.k /*obtain the power (number) to be used.*/ prev=k-1; diff=n-@.prev /*these are used for the odd powers. */ if n//2==0 then z=prv**2 /*Even power? Then square the number.*/ else z=z*!.diff /* Odd " " mult. by pow diff.*/ !.n=z /*remember for other multiplications. */ prv=z /*remember for squaring the numbers. */ end /*k*/ call show /*display the expression and its value.*/ end /*e*/ end /*until nums ···*/
exit /*stick a fork in it, we're all done. */ /*────────────────────────────────POWERTREE subroutine────────────────────────*/ powerTree: arg y 1 oy; $= /*Z is the result; $ is the power tree.*/ if y=0 | y=1 then return y /*handle special cases for zero & unity*/
- .=0; @.=0; #.0=1 /*define default & initial array values*/
/* [↓] add blank "flag" thingy──►list.*/ do while \(y//2); $=$ ' ' /*reduce "front" even power #s to odd #*/ if y\==oy then $=y $ /*(only) ignore the first power number*/ y=y%2 /*integer divide the power (it's even).*/ end /*while ···*/
if $\== then $=y $ /*re─introduce the last power number. */ $=$ oy /*insert last power number 1st in list.*/ if y>1 then do while @.y==0; n=#.0; m=0
do while n\==0; q=0; s=n do while s\==0; _=n+s if @._==0 then do; if q==0 then m_=_; #._=q; @._=n; q=_ end s=@.s end /*while s¬==0*/ if q\==0 then do; #.m=q; m=m_; end n=#.n end /*while n¬==0*/ #.m=0 end /*while @.y==0*/
z=@.y
do while z\==0; $=z $; z=@.z; end /*build power list.*/
return space($) /*────────────────────────────────SHOW subroutine─────────────────────────────*/ show: if e<0 then z=format(1/z,,40)/1; _=right(e,w) /*use reciprocal ? */ say left('power tree for ' _ " is: " $,60) '═══' x"^"_ ' is: ' z; return</lang> output when using the default inputs:
power tree for -4 is: 1 2 4 ═══ 2^-4 is: 0.0625 power tree for -3 is: 1 2 3 ═══ 2^-3 is: 0.125 power tree for -2 is: 1 2 ═══ 2^-2 is: 0.25 power tree for -1 is: 1 ═══ 2^-1 is: 0.5 power tree for 0 is: 0 ═══ 2^ 0 is: 1 power tree for 1 is: 1 ═══ 2^ 1 is: 2 power tree for 2 is: 1 2 ═══ 2^ 2 is: 4 power tree for 3 is: 1 2 3 ═══ 2^ 3 is: 8 power tree for 4 is: 1 2 4 ═══ 2^ 4 is: 16 power tree for 5 is: 1 2 3 5 ═══ 2^ 5 is: 32 power tree for 6 is: 1 2 3 6 ═══ 2^ 6 is: 64 power tree for 7 is: 1 2 3 5 7 ═══ 2^ 7 is: 128 power tree for 8 is: 1 2 4 8 ═══ 2^ 8 is: 256 power tree for 9 is: 1 2 3 6 9 ═══ 2^ 9 is: 512 power tree for 10 is: 1 2 3 5 10 ═══ 2^10 is: 1024 power tree for 11 is: 1 2 3 5 10 11 ═══ 2^11 is: 2048 power tree for 12 is: 1 2 3 6 12 ═══ 2^12 is: 4096 power tree for 13 is: 1 2 3 5 10 13 ═══ 2^13 is: 8192 power tree for 14 is: 1 2 3 5 7 14 ═══ 2^14 is: 16384 power tree for 15 is: 1 2 3 5 10 15 ═══ 2^15 is: 32768 power tree for 16 is: 1 2 4 8 16 ═══ 2^16 is: 65536 power tree for 17 is: 1 2 4 8 16 17 ═══ 2^17 is: 131072 power tree for 191 is: 1 2 3 5 7 14 19 38 57 95 190 191 ═══ 3^191 is: 13494588674281093803728157396523884917402502294030101914066705367021922008906273586058258347 power tree for 81 is: 1 2 3 5 10 20 40 41 81 ═══ 1.1^81 is: 2253.240236044012487937308538033349567966729852481170503814810577345406584190098644811