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


component RationalNumbers;
  type Rational;
       Rational(Numerator = integer, Denominater = integer) -> Rational;
 
       Rational + Rational -> Rational; 
       Rational - Rational -> Rational;
       Rational * Rational -> Rational; 
       Rational / Rational -> Rational;
 
       Rational == Rational -> boolean; 
       Rational <> Rational -> boolean; 
       Rational >= Rational -> boolean; 
       Rational <= Rational -> boolean;
       Rational >  Rational -> boolean; 
       Rational <  Rational -> boolean;
 
       + Rational -> Rational;
       - Rational -> Rational;
       abs(Rational) -> Rational;
 
       Rational(integer) -> Rational;
       Numerator(Rational) -> integer;
       Denominator(Rational) -> integer;
  begin
       Rational(A,B) = Rational:[A;B];
 
       R1 + R2 = Normalize( R1.A * R2.B + R1.B * R2.A, R1.B * R2.B);
       R1 - R2 = Normalize( R1.A * R2.B - R1.B * R2.A, R1.B * R2.B);
       R1 * R2 = Normalize( R1.A * R2.A, R1.B * R2.B);
       R1 / R2 = Normalize( R1.A * R2.B, R1.B * R2.A);
 
       R1 == R2 = [ R = (R1 - R2); R.A == 0]; 
       R1 <> R2 = [ R = (R1 - R2); R.A <> 0];
       R1 >= R2 = [ R = (R1 - R2); R.A >= 0];
       R1 <= R2 = [ R = (R1 - R2); R.A <= 0];
       R1 > R2  = [ R = (R1 - R2); R.A > 0];
       R1 < R2  = [ R = (R1 - R2); R.A < 0];
 
       + R = R;
       - R = Rational(-R.A, R.B);
 
       abs(R) = Rational(abs(R.A), abs(R.B)); 
       Rational(I) = Rational (I, 1);
       Numerator(R) = R.A;
       Denominator(R) = R.B;
 
				<< internal definitions >>
 
       Normalize (A = integer, B = integer) -> Rational;
       Normalize (A, B) = [ exception( B == 0, "Illegal Rational Number");
	                    Common = GCD(abs(A), abs(B)); 
			    if B < 0 then Rational(-A / Common, -B / Common)
			             else Rational( A / Common,  B / Common) ];
 
       GCD (A = integer, B = integer) -> integer;
       GCD (A, B) = [ if A == 0 then return(B);   
	              if B == 0 then return(A); 
		      if A > B  then GCD (B, mod(A,B))
 		                else GCD (A, mod(B,A)) ]; 
 
end component RationalNumbers;