From: jbrock@csfb1.fir.fbc.com (John Brock)
Subject: REXX math functions
Reply-To: uunet!csfb1!jbrock
Organization: First Boston Corporation
Date: Tue, 6 Oct 1992 00:05:46 GMT

I am wondering about the state of REXX math functions.  I haven't
been reading about them here (but I'm new), and I don't see them
in the FAQ file.

I had originally thought that math functions (sqrt, log, sin, etc)
had been left out of REXX because it was too difficult to implement
them with REXX style infinite precision.  Then I was asked to
write such a package, and I discovered it was not that difficult
after all.  I wrote a CMS exec, entirely in REXX, which included
all the usual pocket calculator math functions, was reasonably
efficient (and could be compiled to increase efficiency by a factor
of 10 to 40), and returned all answers to arbitrary precision.
It can, for example, calculate pi to 1000 places in about 20 seconds
(VIRTCPU = 16 sec, for CMS people), and of course is much faster with
more reasonable precisions.  A typical call might look like this:

   x = 'RXMATH'(25, 'POW', 5, 3.8)

i.e., 5 to the power of 3.8 to 25 places (= 452.9872897985597071691338).

The reason I am writing is I just want to put in a plug for this
format for built-in REXX math functions.  (Of course a built-in
math function would not need a precision argument, as it would know
the current numeric digits setting).  I think it would be a
mistake for there to be a separate log function and square root
function and so on -- it just clutters up the name space and makes it
harder to add new math functions later.  I think it would be much more
elegant to put all math functions in a single REXX function and
use one of the arguments to specify the function required.  You
would of course have to depart from the REXX convention of single
letter arguments, but I think it would be worth it.

I really didn't do anything terribly clever writing RXMATH.  I
took the specified precision, doubled it to guarantee that there would
be no rounding errors, then just calculated the standard infinite
series until the sum no longer changed when new elements were added
(because they had gotten too small), and handed back the result
rounded to the requested precision.  As I said, this is reasonably
efficient (and extremely accurate), and I can see no reason why this
couldn't be part of the REXX interpreter.

I actually did do one clever thing people might find interesting.
I have a "calc" function where you could do something like this:

   x = 'RXMATH'(25, 'CALC', 'sqrt(2 * sin(ln(2)) + 1)')

(the result is 1.509278818716829936251786).  The third argument is
a string which is interpreted, can contain any REXX function
(including external function calls), and in which the REXX math
functions are evaluated directly.  The clever thing was that I still
doubled the precision at the beginning, and kept all intermediate
results at the doubled precision, and only rounded down when I
returned the result.  This does wonderful things for the accuracy
of complicated expressions.  (When the third argument here is omitted
my exec goes into an interpreted "REXX shell", but I don't think
we would want that as standard REXX).

If anyone is interested in my code let me know.  I would have to
get permission from someone here to post it to the net, but that
would probably be no problem.  There are actually two execs, one
of which can be compiled and the other handles the interpretive
"calc" function.  They will run under either CMS or TSO.  I don't
know about UNIX, as we have no UNIX REXX interpreter here.

I am sure people have already thought about this.  I have seen
some math packages, but none that were completely general.  For
completeness, my functions are: fact(x), perm(x,y), comb(x,y),
sqrt(x), pow(x,y), log(x,y) [log of y to any base x], exp(x), ln(x),
pi(), sin(x), cos(x), tan(x), cot(x), sec(x), csc(x), arcsin(x),
arccos(x), arctan(x), arccot(x), arcsec(x), arccsc(x), calc(str).
RXMATH will print a result if called from the command line.  If
called as a function and given bad arguments it returns nothing,
hopefully causing your exec to blow up, the way a built-in
function with bad arguments does.

I can be reached at the addresses below.  I can send mail to Usenet
addresses but not to Internet addresses.

-- 
John Brock (212) 909-4662
The First Boston Corporation
12 East 49th Street
New York, NY 10017
uunet!csfb1!jbrock
jbrock@csfb1.fir.fbc.com
Newsgroups: comp.lang.rexx