DIRECTORY Basics, Real, ShortRational; ShortRationalImpl: CEDAR PROGRAM IMPORTS Basics, Real EXPORTS ShortRational = BEGIN Inverse: PROC [real: REAL] RETURNS [REAL] ~ {RETURN [1.0/real]}; FloorN: PROC [real: REAL] RETURNS [NAT] ~ {RETURN [Real.FixI[real]]}; 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. ShortRationalImpl.mesa Michael Plass, May 2, 1984 10:40:13 am PDT This is a separate procedure to make sure that Real.RealException gets caught. This is a separate procedure to make sure that Real.RealException gets caught. Works correctly for non-negative arguments only. Êÿ˜J™J™*J˜šÏk œ˜&J˜—šœ ˜ Jšœ ˜Jšœ˜šœ˜J˜—š Ïnœœœœœœ ˜@JšœN™NJ˜—š žœœœœœœ˜EJšœN™NJ™0J˜—š žœœœœœ"˜LJšœœœ˜Jšœœ˜ Jšœœ˜šœœœ˜-Jšœœ˜Jšœœ ˜Jšœœ˜ Jšœœ˜J˜J˜šœ˜Jšœœ˜Jšœœ˜Jšœœœ!˜4Jšœœœ!˜4Jšœœœœœœœœ˜5Jšœ˜J˜Jšœ ˜ Jšœ ˜ Jšœ˜Jš˜—Jšœ œ˜Jšœ˜—Jšœ˜Jšœ˜Jšœ œ ˜0Jšœ˜J˜—Jšœ˜——…—¦½