ScaledImpl.mesa
Created February 16, 1983
Edited by Michael Plass, March 2, 1983 10:43 am
DIRECTORY
Basics,
Real,
Scaled
;
ScaledImpl: CEDAR PROGRAM
IMPORTS Basics, Real, Scaled
EXPORTS Scaled
= BEGIN
bitsPerWord: INTEGER = Basics.bitsPerWord;
Value: TYPE = Scaled.Value;
TIMES: PUBLIC PROC [a, b: Value] RETURNS [Value] = {
pos: BOOLEAN ← (a.integerPart >= 0) = (b.integerPart >= 0);
prod: Value;
IF a.integerPart < 0 THEN a ← a.UMINUS[];
IF b.integerPart < 0 THEN b ← b.UMINUS[];
prod.fraction ← Basics.HighHalf[Basics.LongMult[a.fraction, b.fraction] + (CARDINAL[LAST[NAT]]+1)];
prod.integerPart ← a.integerPart * b.integerPart;
prod ← LOOPHOLE[
LOOPHOLE[prod, LONG CARDINAL] + Basics.LongMult[a.integerPart, b.fraction] + Basics.LongMult[a.fraction, b.integerPart]
];
RETURN[IF pos THEN prod ELSE prod.UMINUS[]];
};
DIVIDE: PUBLIC PROC [a, b: Value] RETURNS [Value] = {
RETURN[Scaled.FromReal[a.Float[]/b.Float[]]];
};
Scale: PUBLIC PROC [a: Value, scale: INTEGER] RETURNS [Value] = {
IF scale >= 0 THEN {
WHILE scale >= bitsPerWord DO
a.integerPart ← LOOPHOLE[a.fraction];
a.fraction ← 0;
scale ← scale - bitsPerWord;
ENDLOOP;
a.integerPart ← INTEGER[Basics.BITSHIFT[a.integerPart, scale]] + INTEGER[Basics.BITSHIFT[a.fraction, scale-bitsPerWord]];
a.fraction ← Basics.BITSHIFT[a.fraction, scale];
}
ELSE {
sign: CARDINAL = IF a.integerPart >= 0 THEN 0 ELSE LAST[CARDINAL];
WHILE scale <= -bitsPerWord DO
a.fraction ← LOOPHOLE[a.integerPart];
a.integerPart ← LOOPHOLE[sign];
scale ← scale + bitsPerWord;
ENDLOOP;
a.fraction ← CARDINAL[Basics.BITSHIFT[a.integerPart, scale+bitsPerWord]] + CARDINAL[Basics.BITSHIFT[a.fraction, scale]];
a.integerPart ← INTEGER[Basics.BITSHIFT[a.integerPart, scale]] + INTEGER[Basics.BITSHIFT[sign, scale+bitsPerWord]];
};
RETURN[a];
};
END.