Decimal floating point number to binary: Difference between revisions

→‎{{header|REXX}}: simplified some code; optimized several DO loops, elided dead code, added/changed comments and whitespace.
(Add Factor example)
(→‎{{header|REXX}}: simplified some code; optimized several DO loops, elided dead code, added/changed comments and whitespace.)
Line 1,147:
<lang rexx>/*REXX pgm converts any number in a base to another base including fractions; bases≤242.*/
parse arg number toBase inBase digits . /*obtain optional arguments from the CL*/
if toBase=='' | toBase=="," then toBase=10 10 /*Not specified? Then use the default.*/
if inBase=='' | inBase=="," then inBase=10 10 /* " " " " " " */
if digits=='' | digits=="," then digits=60 60 /* " " " " " " */
if number=='' | number=="," then call err "no number specified."
if \datatype(toBase, 'W') then call err "invalid toBase: " toBase
Line 1,155:
if \datatype(digits, 'W') then call err "invalid digits: " digits
numeric digits max(digits, length(number)) + 5 /*use a bigger numeric decimal digits. */
$= base(number, toBase, inBase) /*convert the # from a base to a base. */
numeric digits digits /*use a smaller numeric digs*/
if toBase==10 then if pos(., $)\==0 then $= format($) /*maybe use the FORMAT BIF.*/
say number ' (in base' inBase") = " $ ' (in base' toBase")."
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
base: procedure; parse arg x 1 s 2 1 ox,tt,ii,,oS
@#= 0123456789; @abc= 'abcdefghijklmnopqrstuvwxyz'; @abcu= @abc; upper @abcu
dontUse= @#'.+-'@abc || @abcu"0708090a0b0c0d"x; OK= @# || @abcu || @abc
$= OK || space( translate( xrange('1'x, "fe"x), , dontUse), 0) /*max base string.*/
m= length($) - 1 /*M: is the maximum base. */
if tt=='' then tt=10 10 /*assume base 10 if omitted.*/
if ii=='' then ii=10 10 /*assume base 10 if omitted.*/
i= abs(ii); t= abs(tt); if t==999 | t==" /*"use absolute thenvalues t=mfor I&T*/
if t==999 | t=="*" then t= m if n/*T==0999 or *? then n=Then use max.*/
if t>m then call err 'invalid range for ToBase:' t"; the range is: " 2 m
if i>m then call err 'invalid range for InBase:' i"; the range is: " 2 m
!= substr($, 1 + 10 * (tt<0), t) /*character string for base. */
if tt<0 then != 0 || ! /*prefixNet abase? zero if negPrefix basea zero. */
if x=='' then return left(!, t) /*Is X null? Show base chars*/
@=substr($, 1 + 10 * (ii<0), i) /*@: legal chars for base X.*/
if s='-' | s="+" then do; x= substr(x, 2); oS= s /*stripelide the sign character., */
end oS=s /* ··· and save the original sign. ·*/
if (ii>10 & ii<37) | (ii<0 & ii>-27) then upper x /*should X be uppercased ? end*/
if (ii>10 & ii<37) | (ii<0 & ii>-27) then upper x /*should we uppercase X ? */
parse var x w '.' g /*sep whole from fraction. */
if pos('-', x)>0 | pos("+", x)>0 |, x==. | x=='' | , /*too many signs, bare . /*too many pluses or minuses?*/
x==. | x=='' |, /*bare decimal point or null?*/
pos(., g)>0 then call err 'illegal number: ' ox /*too many decimal points ? */
items.1 __=w 0 || g; _= verify(__, @'.') /*# ofhave wholeany partunusual "digits". ? */
items.2 = 0 /*# of fractional "digits". */
__=w || g; _=verify(__, @'.') /*# have any unusual digits? */
if _\==0 then call err 'illegal char in number:' ox 'char=' substr(__, _, 1)
if i\==10 then do /*convert────────────────────────────────convert # base I──►baseI─►base 10ten.*/
_=0; p=0; do j=length(w) to 1 by -1 while /*convert the whole # part. */w\==''
_= do_ + j=length(w)( pos( tosubstr(w, j, 1), by @)-1) * whilei**p); w\p==''p+1
end _=_ + ((/*j*/ pos( substr(w, j, 1), @) - 1) /*increase power of i*base [↑]*p)/
w=_; p=1; _=0 p=p + 1 /*increase power[↓] ofconvert thefractional base.part*/
do endj=1 for /*j*/length(g)
w=_; _=0; p=1 _= _ + (( pos( substr(g, j, 1), @)-1)/i**convertp); fractional part. */p=p+1
do j=1 for length(g); _=_ + (( pos( substr(g, end /*j,*/ 1), @)-1)/i*increase power of base [↑]*p)/
pg= p + 1 /*increase power of the base.*/_
end /*j*/
g=_
end
else if g\=='' then g= "."g /*reinsert period if needed. */
if t\==10 then do /*────────────────────────────────convert # base ten─►base T.*/
 
if t\==10 then do if w\=='' then do /*convert base10whole #number topart. base T.*/
if w\=='' then do do j=1 until /t*convert*j>w; whole numberend part. /*j*/
do jn=1; _=t**j; if _>w then leave
do endk=j-1 to /1 by -1; _= t*j*/k
n=n || substr(!, 1 + w%_, 1); w= w // _
do end /*k=j-1*/ to 1 by -1; _= t**k; /*remainder d=w %// _*/
w= n=n || substr(!, 1+dw, 1)
w=w // _ /*modulus = // */end
if g\=='' then do; n= end /*kconvert fractional part. */
w=n || substr(!, 1 do digits()+w,1 while g\==0; p= g*t; g= p//1)
end n= n || substr(!, 1 + p%1, 1)
if g\=='' then do; n= /*convert fractional part.end /*digits ···*/
if n==0 then do digits() +1 while g\n==0
if n\=='' then n= '.'n /*only a p=gfraction?*t; g=p//1; d=p % 1
g= n=n || substr(!, d+1, 1)
end /*digits ···*/
if n==0 then n=
if n\=='' then n='.'n /*only a fraction?*/
g=n
end
end
return oS || word( strip( space(w), 'L', 0)strip( strip(g, , 0), "T", .) 0, 1)
/*──────────────────────────────────────────────────────────────────────────────────────*/
err: say; say '***error***: ' arg(1); say; exit 13</lang>