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


procedure main()
   limit := 2^19
 
   write("Perfect numbers up to ",limit," (using rational arithmetic):")
   every write(is_perfect(c := 2 to limit))
   write("End of perfect numbers")
 
   # verify the rest of the implementation
 
   zero := makerat(0)          # from integer
   half := makerat(0.5)        # from real
   qtr  := makerat("1/4")      # from strings ...
   one  := makerat("1")
   mone := makerat("-1")
 
   verifyrat("eqrat",zero,zero)
   verifyrat("ltrat",zero,half)
   verifyrat("ltrat",half,zero)
   verifyrat("gtrat",zero,half)
   verifyrat("gtrat",half,zero)
   verifyrat("nerat",zero,half)
   verifyrat("nerat",zero,zero)
   verifyrat("absrat",mone,)
 
end
 
procedure is_perfect(c)       #: test for perfect numbers using rational arithmetic
   rsum := rational(1, c, 1)
   every f := 2 to sqrt(c) do 
      if 0 = c % f then 
         rsum := addrat(rsum,addrat(rational(1,f,1),rational(1,integer(c/f),1)))   
   if rsum.numer = rsum.denom = 1 then 
      return c
end