Task

Create a reasonably complete implementation of rational arithmetic in the particular language using the idioms of the language.



Example

Define a new type called frac with binary operator "//" of two integers that returns a structure made up of the numerator and the denominator (as per a rational number).

Further define the appropriate rational unary operators abs and '-', with the binary operators for addition '+', subtraction '-', multiplication '×', division '/', integer division '÷', modulo division, the comparison operators (e.g. '<', '≤', '>', & '≥') and equality operators (e.g. '=' & '≠').

Define standard coercion operators for casting int to frac etc.

If space allows, define standard increment and decrement operators (e.g. '+:=' & '-:=' etc.).

Finally test the operators:
Use the new type frac to find all perfect numbers less than 219 by summing the reciprocal of the factors.



Related task

   Perfect Numbers


      *FLOAT64
      DIM frac{num, den}
      DIM Sum{} = frac{}, Kf{} = frac{}, One{} = frac{}
      One.num = 1 : One.den = 1
 
      FOR n% = 2 TO 2^19-1
        Sum.num = 1 : Sum.den = n%
        FOR k% = 2 TO SQR(n%)
          IF (n% MOD k%) = 0 THEN
            Kf.num = 1 : Kf.den = k%
            PROCadd(Sum{}, Kf{})
            PROCnormalise(Sum{})
            Kf.den = n% DIV k%
            PROCadd(Sum{}, Kf{})
            PROCnormalise(Sum{})
          ENDIF
        NEXT
        IF FNeq(Sum{}, One{}) PRINT n% " is perfect"
      NEXT n%
      END
 
      DEF PROCabs(a{}) : a.num = ABS(a.num) : ENDPROC
      DEF PROCneg(a{}) : a.num = -a.num : ENDPROC
 
      DEF PROCadd(a{}, b{})
      LOCAL t : t = a.den * b.den
      a.num = a.num * b.den + b.num * a.den
      a.den = t
      ENDPROC
 
      DEF PROCsub(a{}, b{})
      LOCAL t : t = a.den * b.den
      a.num = a.num * b.den - b.num * a.den
      a.den = t
      ENDPROC
 
      DEF PROCmul(a{}, b{})
      a.num *= b.num : a.den *= b.den
      ENDPROC
 
      DEF PROCdiv(a{}, b{})
      a.num *= b.den : a.den *= b.num
      ENDPROC
 
      DEF FNeq(a{}, b{}) = a.num * b.den = b.num * a.den
      DEF FNlt(a{}, b{}) = a.num * b.den < b.num * a.den
      DEF FNgt(a{}, b{}) = a.num * b.den > b.num * a.den
      DEF FNne(a{}, b{}) = a.num * b.den <> b.num * a.den
      DEF FNle(a{}, b{}) = a.num * b.den <= b.num * a.den
      DEF FNge(a{}, b{}) = a.num * b.den >= b.num * a.den
 
      DEF PROCnormalise(a{})
      LOCAL a, b, t
      a = a.num : b = a.den
      WHILE b <> 0
        t = a
        a = b
        b = t - b * INT(t / b)
      ENDWHILE
      a.num /= a : a.den /= a
      IF a.den < 0 a.num *= -1 : a.den *= -1
      ENDPROC