ShortRationalImpl.mesa
Michael Plass, May 2, 1984 10:40:13 am PDT
DIRECTORY Basics, Real, ShortRational;
ShortRationalImpl: CEDAR PROGRAM
IMPORTS Basics, Real
EXPORTS ShortRational
= BEGIN
Inverse: PROC [real: REAL] RETURNS [REAL] ~ {RETURN [1.0/real]};
This is a separate procedure to make sure that Real.RealException gets caught.
FloorN: PROC [real: REAL] RETURNS [NAT] ~ {RETURN [Real.FixI[real]]};
This is a separate procedure to make sure that Real.RealException gets caught.
Works correctly for non-negative arguments only.
FromReal: PUBLIC PROC [real: REAL] RETURNS [ans: ShortRational.Rational] ~ {
abs: REAL ~ ABS[real];
p: NAT ← 1;
q: CARDINAL ← 0;
BEGIN ENABLE Real.RealException => GOTO Done;
f: NAT ← FloorN[abs];
r: REAL ← abs-f;
pp: NAT ← p;
qq: CARDINAL ← q;
p ← f;
q ← 1;
WHILE r # 0 DO
rinv: REAL ← Inverse[r];
fnew: NAT ← FloorN[rinv];
pnew: LONG CARDINAL ← Basics.LongMult[fnew, p] + pp;
qnew: LONG CARDINAL ← Basics.LongMult[fnew, q] + qq;
IF pnew > NAT.LAST OR qnew > CARDINAL.LAST THEN EXIT;
pp ← p;
qq ← q;
p ← pnew;
q ← qnew;
r ← rinv - fnew;
ENDLOOP;
EXITS Done => NULL;
END;
ans.numerator ← p;
ans.denominator ← q;
IF real < 0 THEN ans.numerator ← -ans.numerator;
};
END.