diff: rat - rational numbers module.

Bert Thompson aet at hydra.cs.mu.oz.au
Fri Mar 27 18:21:31 AEDT 1998


Vanessa Joy TEAGUE <vjteag at students.cs.mu.oz.au> writes:

Hi Vanessa,

These are all good changes. I have a few simple suggestions, which
you can consider to be nitpicks since your code is pretty
good as it stands.

|compiler/rat.m:
...
|	Change the '=' function so that '='(r(An, Ad), r(Bn, Bd)) 
|	is evaluated by checking An*Bd = Ad*Bn.

I think you had this right the first time. If you cross-multiply this
way, you're more likely to hit MAXINT. You should just compare the
normalised forms of the rationals as you did before. Make sure
all operations return rationals in the normal form.

|	Change the '+' and '-' functions so that the numerator and
|	denominator of the sum are divided through by the g.c.d. of 
|	the denominators of the summands before adding.  This reduces
|	the chances of exceeding MAXINT during calculations. 
...
|rat:'*'(r(An, Ad), r(Bn, Bd)) = ratnorm(r(An*Bn, Ad*Bd)).

The multiply can avoid MAXINT better by using a couple of judicious GCDs:

	(n1/d1) * (n2/d2) =
		n1/g1 * n2/g2
		-------------	where g1 = gcd n1 d2; g2 = gcd n2 d1
		d1/g2 * d2/g1

|rat:'-'(r(An, Ad), r(Bn, Bd)) 
|	= ratnorm(r(int:'-'(An*(Bd//Gcd), Bn*(Ad//Gcd)), Ad*(Bd//Gcd))) :-
|	Gcd = gcd(Ad, Bd).

Also, you can probably implement subtraction more easily in terms
of addition:

	rat1 - rat2 = rat1 + negate rat2

Maybe division could be done this way:

	rat1 / rat2 = rat1 * inverse rat2

But you'd have to implement an "inverse" function, hence this
recommendation is debatable.

Hope this is useful,
Bert
-----------------------------------------------
bert thompson			aet at cs.mu.oz.au
-----------------------------------------------



More information about the developers mailing list