Decimal floating point number to binary: Difference between revisions
(→{{header|REXX}}: changed/added comments, re-did a DO loop, removed an erroneous error check. -- ~~~~) |
m (→{{header|REXX}}: made a statement shorter (so it fits one line) . -- ~~~~) |
||
Line 28: | Line 28: | ||
/*──────────────────────────────────BASE subroutine─────────────────────*/ |
/*──────────────────────────────────BASE subroutine─────────────────────*/ |
||
base: procedure; parse arg x 1 s 2 1 ox,tt,ii |
base: procedure; parse arg x 1 s 2 1 ox,tt,ii |
||
@#=0123456789; @abc='abcdefghijklmnopqrstuvwxyz'; |
@#=0123456789; @abc='abcdefghijklmnopqrstuvwxyz'; @abcu=@abc; upper @abcu |
||
$=$basex() /*char string of max base. */ |
$=$basex() /*char string of max base. */ |
||
m=length($)-1 /*"M" is the maximum base. */ |
m=length($)-1 /*"M" is the maximum base. */ |
Revision as of 23:19, 4 February 2014
Your task is to create a program that takes a decimal floating point number and displays its binary representation and vice-versa: takes a floating point binary number and outputs its decimal representation.
The output would be something like this:
23.34375 => 10111.01011
1011.11101 => 11.90625
REXX
This REXX version will handle any number of digits, with bases up to 242 (using extended ASCII characters).
Bases up to 62 will just use decimal digits along with upper and lowercase (Latin) letters.
This REXX program is a modified version of the original program which can handle any base (no limit),
and the original program did more extensive error checking.
This program handles numbers with leading signs (-, +).
Bases that are negative are also supported (which won't be explained here).
<lang rexx>/*REXX programs converts any number in a base to another base; bases≤242*/
parse arg number toBase inBase digits .
if toBase== | toBase==',' then toBase=10 /*Specified? No, use default*/
if inBase== | inBase==',' then inBase=10 /* " " " " */
if digits== | digits==',' then digits=60 /* */
if number== | number==',' then call err 'no number specified.'
if \datatype(toBase,'W') then call err 'invalid toBase: ' toBase
if \datatype(inBase,'W') then call err 'invalid inBase: ' inBase
if \datatype(digits,'W') then call err 'invalid digits: ' digits
numeric digits max(digits,length(number))+5 /*use a bigger numeric digs.*/
$=base(number,toBase,inBase) /*convert the number given. */
numeric digits digits /*use a smaller numeric digs*/
if toBase==10 then if pos('.',$)\==0 then $=format($) /*maybe use BIF*/
say number ' (in base' inBase") = " $ ' (in base' toBase")."
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────BASE subroutine─────────────────────*/
base: procedure; parse arg x 1 s 2 1 ox,tt,ii
@#=0123456789; @abc='abcdefghijklmnopqrstuvwxyz'; @abcu=@abc; upper @abcu
$=$basex() /*char string of max base. */
m=length($)-1 /*"M" is the maximum base. */
if tt== then tt=10 /*assume base 10 if omitted.*/
if ii== then ii=10 /*assume base 10 if omitted.*/
i=abs(ii); t=abs(tt)
if t==999 | t=="*" then t=m
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 || ! /*prefix a zero if neg base.*/
if x== then return left(!,t)
@=substr($, 1+10*(ii<0), i) /*@ =legal chars for base X.*/
oS= /*original sign placeholder.*/
if s='-' | s="+" then do /*process the sign (if any).*/
x=substr(x,2) /*strip the sign character. */ oS=s /*save the original sign. */ end
if (ii>10 & ii<37) | (ii<0 & ii>-27) then upper x /*uppercase it ? */ if pos('-',x)\==0 |, /*too many minus signs ? */
pos('+',x)\==0 |, /*too many plus signs ? */ x=='.' |, /*is single decimal point ? */ x== then call err 'illegal number: ' ox
parse var x w '.' g /*sep whole from fraction. */ if pos('.',g)\==0 then call err 'illegal number: ' ox /*too many . */ items.1=0 /*# of whole part "digits". */ items.2=0 /*# of fractional "digits". */ __=w||g /*verify re-composed number.*/ _=verify(__,@'.') /*# have any unusual digits?*/ if _\==0 then call err 'illegal char in number:' ox 'char=' substr(__,_,1) if i\==10 then do /*convert # base I──►base 10*/
_=0; p=0 /*convert the whole # part. */ do j=length(w) to 1 by -1 while w\== _=_ + ((pos(substr(w,j,1),@)-1) * i**p) p=p+1 /*increase power of the base*/ end /*j*/ w=_; _=0; p=1 /*convert fractional part. */ do j=1 for length(g);_=_+((pos(substr(g,j,1),@)-1)/i**p) p=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 base10 # to base T*/
if w\== then do /*convert whole number part.*/ do j=1; _=t**j; if _>w then leave end /*j*/ n= do k=j-1 to 1 by -1; _=t**k; d=w%_ n=n || substr(!,1+d,1) w=w//_ /*modulus = // */ end /*k*/ w=n||substr(!,1+w,1) end if g\== then do; n= /*convert fractional part. */ do digits()+1 while g\==0 p=g*t; g=p//1; d=p%1 n=n || substr(!,d+1,1) end /*digits()+1 ···*/ 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) /*──────────────────────────────────$BASEX subroutine───────────────────────────────────────────────────*/ $basex:return @#||@abcu||@abc||space(translate(xrange('1'x,"fe"x),,@#'.+-'@abc||@abcu"0708090a0b0c0d"x),0) /*──────────────────────────────────ERR subroutine──────────────────────*/ err: say; say '***error!***: ' arg(1); say; exit 13</lang> output when using the input of: 23.34375 2
23.34375 (in base 10) = 10111.01011 (in base 2).
output when using the input of: 1011.11101 10 2
1011.11101 (in base 2) = 11.90625 (in base 10).
output when using the input of: 3.14159265358979323846264338327950288419716939937510582097494 62
3.14159265358979323846264338327950288419716939937510582097494 (in base 10) = 3.8mHUcirZ3g3aaX5Bn156eBkfOx43HPGx7xT3yBX1Aoh3TAAEolLiHWo8Z4XVLWesfA6 (in base 62).