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


class Rational(n: Long, d:Long) extends Ordered[Rational]
{
   require(d!=0)
   private val g:Long = gcd(n, d)
   val numerator:Long = n/g
   val denominator:Long = d/g
 
   def this(n:Long)=this(n,1)
 
   def +(that:Rational):Rational=new Rational(
      numerator*that.denominator + that.numerator*denominator,
      denominator*that.denominator)
 
   def -(that:Rational):Rational=new Rational(
      numerator*that.denominator - that.numerator*denominator,
      denominator*that.denominator)
 
   def *(that:Rational):Rational=
      new Rational(numerator*that.numerator, denominator*that.denominator)
 
   def /(that:Rational):Rational=
      new Rational(numerator*that.denominator, that.numerator*denominator)
 
   def unary_~ :Rational=new Rational(denominator, numerator)
 
   def unary_- :Rational=new Rational(-numerator, denominator)
 
   def abs :Rational=new Rational(Math.abs(numerator), Math.abs(denominator))
 
   override def compare(that:Rational):Int=
      (this.numerator*that.denominator-that.numerator*this.denominator).toInt
 
   override def toString()=numerator+"/"+denominator
 
   private def gcd(x:Long, y:Long):Long=
      if(y==0) x else gcd(y, x%y)
}
 
object Rational
{
   def apply(n: Long, d:Long)=new Rational(n,d)
   def apply(n:Long)=new Rational(n)
   implicit def longToRational(i:Long)=new Rational(i)
}