| Previous | Table of Contents | Next |
10.4.2.4. Using the Rationals Package
Before I investigate the implementations of the rational-number packages, examine a typical interactive client program. A session with this program might be
A = 1/3 B = -2/4 Enter rational number C > 2/5 Enter rational number D > 3/4 E = A + B is -2/12 A + E * B is 60/144 Bs numerator is -2
Results such as -2/12 and 60/144 make it obvious that nothing in this package is reducing rationals to lowest terms. A good rationals package should do so; I have chosen to omit it in the interest of brevity. It would not be difficult to add to the / operator.
1 with Ada.Text_IO, Ada.Integer_Text_IO;
2 with HB.Rationals, HB.Rationals.IO;
3 use HB.Rationals;
4 procedure Show_Package is
5
6 A, B, C, D, E: Rational;
7
8 begin
9
10 A := 1/3;
11 B := 2/(-4);
12 Ada.Text_IO.Put(Item => A = );
13 HB.Rationals.IO.Put(Item => A);
14 Ada.Text_IO.New_Line;
15 Ada.Text_IO.Put(Item => B = );
16 HB.Rationals.IO.Put(Item => B);
17 Ada.Text_IO.New_Line;
18
19 Ada.Text_IO.Put(Item => Enter rational number C > );
20 HB.Rationals.IO.Get(Item => C);
21 Ada.Text_IO.Put(Item => Enter rational number D > );
22 HB.Rationals.IO.Get(Item => D);
23 Ada.Text_IO.New_Line;
24
25 E := A + B;
26 Ada.Text_IO.Put(Item => E = A + B is );
27 HB.Rationals.IO.Put(Item => E);
28 Ada.Text_IO.New_Line;
29
30 Ada.Text_IO.Put(Item => A + E * B is );
31 HB.Rationals.IO.Put(Item => A + E * B);
32 Ada.Text_IO.New_Line;
33
34 Ada.Text_IO.Put(Item => Bs numerator is );
35 Ada.Integer_Text_IO.Put
36 (Item => Numer(B), Width => 1);
37 Ada.Text_IO.New_Line;
38
39 exception
40 when ZeroDenominator =>
41 Ada.Text_IO.Put_Line(Item =>
42 Zero not allowed in denominator; bye-bye.);
43 end Show_Package;
Lines 1-3 provide the expected context clauses and a use for Rationals. The use allows me to use the rational operators in infix form; without a use, I would have to say, for example, in line 10,
A := Rationals./(1,3);
which is unpleasant. The rest of the program illustrates some simple rational arithmetic; note line 25, for example, which looks like an ordinary arithmetic assignment, but in fact, all the operations are rational ones.
In analyzing E := A + B, the compiler can determine that the + is intended to be that for rationals because its two operands (A and B) are of type Rational, as is the return type (E). Similarly in line 31, the expression A + E * B is a rational one because all three operands are, as is the desired Item sent to HB.Rationals.IO.Put. Determining which of several like-named operators is intended is called overload resolution; the compiler can resolve the overloads if and only if it has enough information to do so.
If X is Integer and Y is Rational, the expression X + Y results in a compilation error. This is simply because there is no + defined for this combination of operands; I could add one to the package if I chose to do so; its line in the interface would be
function +(X: Integer; R: Rational) return Rational;
Indeed, nothing prevents me from writing a package providing other mixed operations, such as
function +(X: Integer; F: Float) return Float;
This observation reveals that although mixed operations are not predefined in Ada, you could add these to the language via a suitable (large) collection of overloaded operators. Doing so would not be desirable, however: The compiler would have no trouble resolving all the overloads in a program that used these mixed expressions, but the human reader would quickly get confused. Operator overloading is convenient when used in moderation.
| Previous | Table of Contents | Next |