TamarinDivideImpl.mesa
December 8, 1986 3:05:11 pm PST
Last Edited by: Ross May 18, 1987 2:43:46 pm PDT
DIRECTORY Basics, TamarinDivide;
TamarinDivideImpl: CEDAR PROGRAM
IMPORTS Basics
EXPORTS TamarinDivide =
BEGIN
priorityOfByte: ARRAY [0..256) OF INT
= [-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
Priority: PUBLIC PROC [inNum: INT] RETURNS [priority: NAT ← 0, isZero: BOOL] ~ {
bytePriority: INT;
i: NAT ← 3;
zeroByte: BOOL;
bytePriority ← priorityOfByte[Basics.DoubleShiftRight[[li[inNum]], 8*i].li];
zeroByte ← bytePriority = -1;
THROUGH [0..2] WHILE zeroByte DO
i ← i -1;
bytePriority ← priorityOfByte[Basics.DoubleShiftRight[[li[inNum]], 8*i].li];
zeroByte ← bytePriority = -1;
ENDLOOP;
IF (bytePriority # -1) THEN RETURN [bytePriority + 8*i, FALSE] ELSE RETURN [0, TRUE];
};
OldPriority: PUBLIC PROC [inNum: INT] RETURNS [priority: INT ← 0] ~ {
IF (inNum < 0) THEN inNum ← - inNum;
WHILE (inNum > 0) DO
IF inNum > 256 THEN BEGIN
priority ← priority + 8;
inNum ← Basics.DoubleShiftRight[[li[inNum]], 8].li;
END ELSE BEGIN
IF inNum > 16 THEN BEGIN
priority ← priority + 4;
inNum ← Basics.DoubleShiftRight[[li[inNum]], 4].li;
END ELSE BEGIN
priority ← priority + 1;
inNum ← Basics.DoubleShiftRight[[li[inNum]], 1].li;
END;
END;
ENDLOOP;
RETURN[priority];
};
Divide: PUBLIC PROC [inD1, inD2: INT] RETURNS [quotient, remainder: INT, overFlow: BOOL ← FALSE] ~ {
inD2 is the numerator and inD1 is the divisor
nextExponent: NAT;
priorDivisor: NAT;
divisorNeg: BOOL ← inD1 < 0;
divisorPos: BOOL ← inD1 > 0;
isZero: BOOL;
[priorDivisor, isZero] ← Priority[inD1];
IF isZero THEN RETURN[0, 0, TRUE];
quotient ← 0;
remainder ← inD2;
[nextExponent, isZero] ← Priority[remainder];
nextExponent ← nextExponent - priorDivisor;
WHILE (nextExponent > 0) DO
IF (remainder < 0) # divisorNeg THEN BEGIN
quotient ← quotient - Basics.DoubleShiftLeft[[li[1]], nextExponent].li;
remainder ← remainder + Basics.DoubleShiftLeft[[li[inD1]], nextExponent].li;
END ELSE BEGIN
quotient ← quotient + Basics.DoubleShiftLeft[[li[1]], nextExponent].li;
remainder ← remainder - Basics.DoubleShiftLeft[[li[inD1]], nextExponent].li;
END;
[nextExponent, isZero] ← Priority[remainder];
nextExponent ← nextExponent - priorDivisor;
ENDLOOP;
IF (nextExponent = 0) THEN BEGIN
IF (remainder < 0) # divisorNeg THEN BEGIN
quotient ← quotient - 1;
remainder ← remainder + inD1;
END ELSE BEGIN
quotient ← quotient + 1;
remainder ← remainder - inD1;
END;
END;
Adjust so remainder has the correct sign.
IF (remainder < 0) # (inD2 < 0) THEN BEGIN
IF ((remainder < 0) AND divisorPos) OR ((remainder > 0) AND divisorNeg) THEN BEGIN
quotient ← quotient - 1;
remainder ← remainder + inD1;
END ELSE BEGIN
quotient ← quotient + 1;
remainder ← inD1 - remainder;
END;
END;
RETURN[quotient, remainder, FALSE];
};
END.