/*NetRexx program to calculate the Nth root of X, with DIGS accuracy. */ class nth_root method main(args=String[]) static if args.length < 2 then do say "at least 2 arguments expected" exit end x = args[0] root = args[1] if args.length > 2 then digs = args[2] if root=='' then root=2 if digs = null, digs = '' then digs=20 numeric digits digs say ' x = ' x say ' root = ' root say 'digits = ' digs say 'answer = ' root(x,root,digs) method root(x,r,digs) static --procedure; parse arg x,R 1 oldR /*assign 2nd arg-->r and rOrig. */ /*this subroutine will use the */ /*digits from the calling prog. */ /*The default digits is 9. */ R = r oldR = r if r=0 then do say say '*** error! ***' say "a root of zero can't be specified." say return '[n/a]' end R=R.abs() /*use absolute value of root. */ if x<0 & (R//2==0) then do say say '*** error! ***' say "an even root can't be calculated for a" - 'negative number,' say 'the result would be complex.' say return '[n/a]' end if x=0 | r=1 then return x/1 /*handle couple of special cases.*/ Rm1=R-1 /*just a fast version of ROOT-1 */ oldDigs=digs /*get the current number of digs.*/ dm=oldDigs+5 /*we need a little guard room. */ ax=x.abs() /*the absolute value of X. */ g=(ax+1)/r**r /*take a good stab at 1st guess. */ -- numeric fuzz 3 /*fuzz digits for higher roots. */ d=5 /*start with only five digits. */ /*each calc doubles precision. */ loop forever d=d+d if d>dm then d = dm /*double the digits, but not>DM. */ numeric digits d /*tell REXX to use D digits. */ old=0 /*assume some kind of old guess. */ loop forever _=(Rm1*g**R+ax)/R/g**rm1 /*this is the nitty-gritty stuff.*/ if _=g | _=old then leave /*computed close to this before? */ old=g /*now, keep calculation for OLD. */ g=_ /*set calculation to guesstimate.*/ end if d==dm then leave /*found the root for DM digits ? */ end _=g*x.sign() /*correct the sign (maybe). */ if oldR<0 then return _=1/_ /*root < 0 ? Reciprocal it is.*/ numeric digits oldDigs /*re-instate the original digits.*/ return _/1 /*normalize the number to digs. */