Temperature conversion/REXX: Difference between revisions

m
→‎{{header|REXX}}: changed extra digits and optimized the sqrt function, added a comment.
m (→‎{{header|REXX}}: replace the COMMA subroutine with a simpler COMMAS subroutine.)
m (→‎{{header|REXX}}: changed extra digits and optimized the sqrt function, added a comment.)
Line 2:
 
=={{header|REXX}}==
<lang rexx>/*REXX program converts temperatures for a large number of temperature scales.*/
 
call e /*let's see the precision we can use. */
Line 371:
/*──────────────────────────────────one─liner subroutines───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/
?: parse arg y; if not\=='' then do; if noS\=='' then if left(y,noL)==noS then return 0; if noE\=='' then if right(y,noL)==noE then return 0; end; if all | y==! then return 1; return 0
 
commas:procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n,#,"M"); e=verify(n,#'0',,verify(n,#"0.",'M'))-4; do j=e to b by -3; _=insert(',',_,j); end /*j*/; return _
 
e: e = 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932; return e
 
isInt: return datatype(arg(1), 'W') /*is the argument a whole number (integer)?*/
 
exp: procedure; parse arg x; ix=x%1; if abs(x-ix)>.5 then ix=ix+sign(x); x=x-ix; z=1; _=1; w=z; do j=1; _=_*x/j; z=(z+_)/1; if z==w then leave;w=z;end;if z\==0 then z=z*e()**ix;return z/1
 
ln: procedure; parse arg x; call e; ig=x>1.5; is=1-2*(ig\==1); ii=0; xx=x; return ln..()
ln..: do while ig & xx>1.5 | \ig & xx<.5;_=e;do k=-1;iz=xx*_**-is;if k>=0 & (ig & iz<1 | \ig & iz>.5) then leave;_=_*_;izz=iz;end;xx=izz; ii=ii+is*2**k; end; x=x*e**-ii-1; z=0;_=-1;p=z;do k=1; _=-_*x; z=z+_/k; if z=p then leave;p=z; end; return z+ii
 
pow: procedure; parse arg x,y; if y=0 then return 1; if x=0 then return 0; if isInt(y) then return x**y; if isInt(1/y) then return root(x,1/y,f); return pow.()
pow.: if abs(y//1)=.5 then return sqrt(x)**sign(y)*x**(y%1); return exp(y*ln(x))
 
root: procedure; parse arg x,y; if x=0 | y=1 then return x; if isInt(y) then return rooti(x,y); _=sqrt(x); if y<0 then _=1/_; return _
 
rooti: procedure; parse arg x,y; if x=0 | y=1 then return x; n=y<0; y=abs(y); numeric digits digits()+2; z=abs(x); g=(z+1)/y; m=y-1; numeric fuzz 2; do forever; _=(m*g**y+z)/y/g**m; if _=g then leave; g=_; end; _=g*sign(x); if n then _=1/_; return _
 
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*pluralizer.*/
 
serr: say; say '***error!***'; say; say arg(1); say; exit 13
 
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); p=d; m.i=9; numeric digits 9; g=sqrt.(); m.0=d; m.1=d; do j=2 while p>9; m.j=p; p=p%2+1; end; do k=j+5 to 0 by -1; numeric digits m.k; g=.5*(g+x/g); end; numeric digits d; return (g/1)i
sqrt.: i=; numeric digits 9; numeric form; h=d+6; if x<0 then do; x=-x; i='i'; end; numeric form; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; return g*.5'E'_%2</lang>
parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g*.5'e'_%2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/
numeric digits d; return (g/1)i /*make complex if X < 0.*/</lang>