This task has been flagged for clarification. Code on this page in its current state may be flagged incorrect once this task has been clarified. See this page's Talk page for discussion.


The task is to write a program to transform a decimal number into a fraction in lowest terms.

It is not always possible to do this exactly. For instance, while rational numbers can be converted to decimal representation, some of them need an infinite number of digits to be represented exactly in decimal form. Namely, repeating decimals such as 1/3 = 0.333...

Because of this, the following fractions cannot be obtained (reliably) unless the language has some way of representing repeating decimals:

 67 / 74 = 0.9(054) = 0.9054054...
 14 / 27 = 0.(518) = 0.518518...

Acceptable output:

 0.9054054 → 4527027 / 5000000
 0.518518 → 259259 / 500000

Finite decimals are of course no problem:

 0.75 → 3 / 4 


 
/*NetRexx program to convert decimal numbers to fractions *************
* 16.08.2012 Walter Pachl derived from Rexx Version 2
**********************************************************************/
options replace format comments java crossref savelog symbols
  Numeric Digits 10               /* use "only" 10 digs of precision */
  ratt('0.9054054054','67/74')
  ratt('0.5185185185','14/27')
  ratt('0.75'        ,'3/4')
  ratt('0.905405400',' 693627417/766095958')
  ratt('0.9054054054','67/74')
  ratt('0.1428571428','1/7')
  ratt('35.000','35')
  ratt('35.001','35001/1000')
  ratt('0.00000000001','?')
  ratt('0.000001000001','1/999999')
 
ratt(0.9054054054,'1/3')
 
 
method ratt(d = Rexx,fs = Rexx) public static
 fract=rat(d)
 Say '  'd '->' fract
 Parse fract no '/' de
 If de='' Then x=no
          Else x=no/de
 If x<>d Then
   Say '> '||x 'is different'
 
method rat(in, high='') public static
/**********************************************************************
* rat(number<,high) returns a fraction or an integer that is equal to
* or approximately equal to number.
* Nominator and denominator must not have more than high digits
* 16.08.2012 Walter Pachl derived from Rexx Version 2
**********************************************************************/
  if high=='' then
    high=10**(digits - 1)           /* maximum nominator/denominator */ 
  x=in                                 /* working copy               */
  nom=0                                /* start values nominator     */
  den=1                                /*              denominator   */
  tnom=1                               /*         temp nominator     */
  tden=0                               /*         temp denominator   */
  loop While tnom<=high & tden<=high   /* nominator... not too large */
    n=x.trunc()                        /* take integer part of x     */
    z=tnom;                            /* save temp nominator        */
    tnom=n*tnom+nom;                   /* compute new temp nominator */
    nom=z                              /* assign nominator           */
    z=tden;                            /* save temp denominator      */
    tden=n*tden+den                    /* compute new temp denominato*/
    den=z                              /* assign denominator         */
    if n=x | tnom/tden=in then do
      if tnom>high | tden>high then    /* temp value(s) too large    */
        Leave                          /* don't use them             */
      nom=tnom                         /* otherwise take them as     */
      den=tden                         /* final values               */
      leave                            /* and end the loop           */
      end
    x=1/(x-n)                          /* compute x for next round   */
    end
  If den=1 Then Return nom             /* an integer                 */
           Else Return nom'/'den       /* otherwise a fraction       */