Decimal floating point number to binary

From Rosetta Code
Revision as of 21:52, 4 February 2014 by rosettacode>Gerard Schildberger (→‎{{header|REXX}}: added the REXX language. -- ~~~~)
Decimal floating point number to binary is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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).
This program also handles numbers with leading signs   (-, +). <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 /* */ 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 erx 81,2 m t f'-to' if i>m then call erx 81,2 m i f'-from'

           !=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 erx 53,ox f  /*or a single + or - sign ? */

parse var x w '.' g /*sep whole from fraction. */ if pos('.',g)\==0 then call erx 53,ox f /*too many decimals points? */ 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 erx 48,ox substr(__,_,1) '[for' f i"]" /*oops-sey.*/ if i\==10 then do /*convert # base I──►base 10*/

                                           /*···but only if not 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//_
                                 end     /*k*/
                             w=n||substr(!,1+w,1)
                             end
              if g\== then do;  n=       /*convert fractional part.  */
                                      do digits()+1;   if g==0 then leave
                                      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)</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).