Real constants and functions: Difference between revisions

Content added Content deleted
(Added Axe)
(→‎sqrt (optimized): added/changed comments and whitespace.)
Line 1,573: Line 1,573:


===sqrt (optimized)===
===sqrt (optimized)===
A [principal] square root (SQRT) function for REXX (arbitrary precision):
A [principal] square root (SQRT) function for REXX   (with arbitrary precision):
<lang rexx>/*──────────────────────────────────SQRT subroutine─────────────────────*/
<lang rexx>/*──────────────────────────────────SQRT subroutine───────────────────────────*/
sqrt: procedure; r= /*returns principal SQRT of args.*/
sqrt: procedure; parse arg x; if x=0 then return 0 /*handle 0 case.*/
if \datatype(x,'N') then return '[n/a]' /*Not Applicable ───if not numeric.*/
do j=1 for arg() /*process each argument specified*/
i=; if x<0 then do; x=-x; i='i'; end /*handle complex numbers if X is < 0.*/
a=arg(j) /*extract the argument specified*/
do k=1 for words(a) /*process each number specified. */
d=digits() /*get the current numeric precision. */
r=r sqrt_(word(a,k)) /*calculate sqrt, add to results.*/
m.=9 /*technique uses just enough digits. */
end /*k*/ /* [↑] process each # in Nth arg*/
h=d+6 /*use extra decimal digits for accuracy*/
end /*j*/ /* [↑] process each #s in args. */
numeric digits 9 /*use "small" precision at first. */
return r /*return list of SQRTs calculated*/
numeric form /*force scientific form of the number. */
if fuzz()\==0 then numeric fuzz 0 /*just in case invoker has a FUZZ set.*/
/*──────────────────────────────────SQRT_ subroutine────────────────────*/
sqrt_: procedure; parse arg x; if x=0 then return 0 /*handle 0*/
parse value format(x,2,1,,0) 'E0' with g 'E' _ . /*get the X's exponent.*/
g=(g * .5) || 'e' || (_ % 2) /*1st guesstimate for the square root. */
if pos(',',x)\==0 then x=space(translate(x,,","),0) /*elide comma.*/
/* g= g * .5 'e' (_ % 2) */ /*a shorter & concise version of above.*/
if \datatype(x,'N') then return '[n/a]' /*not numberic? not applicable*/
ox=x /*save the original value of X. */
/*Note: to insure enough accuracy for */
x=abs(x) /*just use positive value of X. */
/* the result, the precision during */
d=digits() /*get the current precision. */
/* the SQRT calculations is increased */
m.=11 /*technique uses just enough digs*/
/* by two extra decimal digits. */
numeric digits m. /*use "small" precision at first.*/
do j=0 while h>9; m.j=h; h=h%2+1 /*compute the sizes (digs) of precision*/
numeric form /*force scientific form of number*/
end /*j*/ /* [↑] precisions are stored in M. */
/*now, we start to do the heavy lifting*/
parse value format(x,2,1,,0) 'E0' with g 'E' _ . /*get X's exponent.*/
g=g * .5'E'_ % 2 /*1st guesstimate for square root*/
do k=j+5 to 0 by -1 /*compute the with increasing digs.*/
p=d + d%4 + 2 /*# of iterations (calculations).*/
numeric digits m.k /*each iteration, increase the digits. */
/*Note: to insure enough accuracy*/
g=(g+x/g) * .5 /*perform the nitty-gritty calculations*/
/*for the result, the precsion */
end /*k*/ /* [↑] * .5 is faster than / 2 */
/*during the SQRT calcuations is */
/* [↓] normalize ──► original digits*/
/*increased by two extra digits. */
numeric digits d /* [↓] make answer complex if X < 0. */
return (g/1)i /*normalize, and add possible I suffix.*/</lang>
do j=0 while p>9; m.j=p; p=p%2+1 /*compute the sizes of precision.*/
<lang rexx> ╔════════════════════════════════════════════════════════════════════╗
end /*j*/ /* [↑] precisions stored in M. */
/* [↓] da rubber meets da road. */
╔═╝ __ ╚═╗
do k=j+5 to 0 by -1 /*computewith increasing digs.*/
numeric digits m.k /*each iteration, increase digits*/
While the above REXX code seems like it's doing a lot of extra work,
g=(g+x/g) * .5 /*do the nitty-gritty calculation*/
it saves a substantial amount of processing time when the precision
end /*k*/ /* [↑] .5* is faster than /2 */
(DIGITs) is a lot greater than the default (default is nine digits).
/* [↓] normalize√──►original dig*/
numeric digits d /*restore the original precision.*/
Indeed, when computing square roots in the hundreds (even thousands)
return (g/1)left('i',ox<0) /*normalize, add possible suffix.*/</lang>
of digits, this technique reduces the amount of CPU processing time
<lang rexx>/*┌────────────────────────────────────────────────────────────────────┐
by keeping the length of the computations to a minimum (due to a large
┌─┘└─┐
precision), while the accuracy at the beginning isn't important for
While the above REXX code seems like it's doing a lot of extra work,
calculating the (first) guesstimate (the running square root guess).
it saves a substantial amount of processing time when the precision
(DIGITs) is a lot greater than the default (which is nine digits).
║ Each iteration of K (approximately) doubles the number of digits, ║
║ but takes almost four times longer to compute (actually, around 3.8). ║
Indeed, when computing square roots in the hundreds (even thousands)
║ ║
of digits, this technique reduces the amount of CPU processing time
║ The REXX code could be streamlined (pruned) by removing the ║
by keeping the length of the computations to a minimum (due to a large
║ The NUMERIC FUZZ 0 statement can be removed if it is known ║
precision), while the accuracy at the beginning isn't important for
║ that it is already set to zero. (which is the default). ║
calculating the (first) guesstimate (the running square root guess).
└─┐ ┌─┘
║ Also, the NUMERIC FORM statement can be removed if it is known ║
└────────────────────────────────────────────────────────────────────┘*/</lang>
║ that the form is SCIENTIFIC (which is the default). ║
║ __ ║
╚═╗╔═╝
╚════════════════════════════════════════════════════════════════════╝</lang>


===sqrt (simple)===
===sqrt (simple)===