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[]];
};
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];
};