WITH text_io, integer_text_io; USE text_io, integer_text_io; -------------------------------------------------------------------- PROCEDURE rats IS -- Simple test of rational_number routines TYPE rational IS RECORD numerator : integer; denominator:integer; END RECORD; a,b,c: rational; -------------------------------------------------------------------- PROCEDURE putrat (caption: string; ratval: rational) IS -- Prints caption followed by rational value BEGIN put (caption); put (ratval.numerator); put ("/"); put (ratval.denominator); new_line; END; FUNCTION hcf (x, y: integer) RETURN integer IS -- Returns the Highest Common Factor of x and y p, q, r: integer; BEGIN p := x; q := y; IF q = 0 THEN q := 1; END IF; LOOP -- Euclidean Algorithm to find HCF r := p mod q; EXIT WHEN r = 0; p := q; q := r; END LOOP; RETURN q; END; FUNCTION reduced (x: rational) RETURN rational IS -- Reduces a rational number to co-prime parts with +ve denominator -- The parts are thus as small as possible and also unique n, d, h: integer; BEGIN -- form a positive denominator IF x.denominator >= 0 THEN n := x.numerator; d := x.denominator; ELSE n := -x.numerator; d := -x.denominator; END IF; -- calculate HCF and divide into numerator and denominator h := hcf (n,d); RETURN (n/h, d/h); END; FUNCTION "/" (x, y: integer) RETURN rational IS -- Forms a rational number from two integers BEGIN RETURN reduced (rational'(x,y)); END; FUNCTION "/" (x, y: rational) RETURN rational IS -- Divides one rational number by another n, d: rational; BEGIN -- the technique used here, which first forms rational numbers from -- numerators and denominators respectively, with co-prime parts, -- helps to remove unnecessary overflows. n := x.numerator / y.numerator; d := x.denominator / y.denominator; RETURN (n.numerator * d.numerator) / (n.denominator * d.denominator); END; FUNCTION "*" (x, y: rational) RETURN rational IS -- Multiplies two rational numbers x1, y1: rational; BEGIN -- forms rational numbers from numerator of each with denominator of -- the other; as this removes common factors helps reduce overflow x1 := x.numerator / y.denominator; y1 := y.numerator / x.denominator; RETURN rational' (x1.numerator * y1.numerator, x1.denominator * y1.denominator); END; FUNCTION "+" ( x, y: rational) RETURN rational IS -- Forms sum of two rational numbers nf, df, xn, xd, yn, yd: integer; BEGIN -- first extracts common factors from numerators and denominators to -- help reduce overflow nf := hcf (x.numerator, y.numerator); df := hcf (x.denominator, y.denominator); xn := x.numerator / nf; yn := y.numerator / nf; xd := x.denominator / df; yd := y.denominator / df; RETURN rational'(nf,df) * rational'(xn*yd + yn*xd, xd*yd); END; FUNCTION "-" (x: rational) RETURN rational IS -- Returns negative of a rational number BEGIN RETURN rational'(-x.numerator, x.denominator); END; FUNCTION "-" (x, y: rational) RETURN rational IS -- Returns difference of two rationals BEGIN RETURN x + (-y); END; -------------------------------------------------------------------- BEGIN a := 7/5; b := 2/3; put_line ("Rational-Numbers Test"); putrat ("a = ",a); putrat ("b = ",b); putrat ("a+b = ",a+b); putrat ("a*b = ",a*b); putrat ("a/b = ",a/b); put_line ("End of Test."); END; -------------------------------------------------------------------