Types and Constants
bitsPerWord: CARDINAL = Basics.bitsPerWord;
BigCardZero: BigCard = BigCardinals.BigFromSmall[0];
BigCardOne: BigCard = BigCardinals.BigFromSmall[1];
BigPowerOfTen:
PUBLIC
PROC [exponent:
CARDINAL]
RETURNS [power:
BC.BigCARD] ~ {
exponent assumed nonnegative, else coerced to abs value.
base:BC.BigCARD ← BC.BigFromSmall[10];
power ← BC.BigFromSmall[1];
IF exponent = 0 THEN RETURN;
--Exponentiation by repeated squaring.
WHILE exponent > 1
DO
IF exponent
MOD 2 = 1
THEN
power ← BC.BigMultiply[power, base];
exponent ← exponent / 2;
base ← BC.BigMultiply[base, base];
ENDLOOP;
power ← BC.BigMultiply[power, base];
};
BigToREAL:
PUBLIC
PROC [in:
BC.BigCARD, reuse:
BOOLEAN ←
FALSE]
RETURNS [out:
REAL] ~ {
outChunk: REAL;
out ← 0.0;
IF BC.BigZero[in] THEN RETURN;
IF NOT reuse THEN in ← BC.BigCopy[in];
FOR index:
CARDINAL
DECREASING IN [0..in.size)
DO
outChunk ← in.contents[index]; -- convert CARDINAL to REAL
out ← out * 65536.0 + outChunk;
ENDLOOP;
};
BigOne:
PUBLIC
PROC [in:
BC.BigCARD]
RETURNS [
BOOLEAN] ~ {
Test if a BigCARD is the integer one.
IF in.size = 1 THEN RETURN[BC.BigToSmall[in] = 1] ELSE RETURN[FALSE]
};
LCToBC:
PUBLIC PROC [lc:
CARD]
RETURNS [bc: BigCard] = {
IF Basics.HighHalf[lc] = 0
THEN {
SELECT Basics.LowHalf[lc]
FROM
0 => RETURN [BigCardZero];
1 => RETURN [BigCardOne];
ENDCASE;
bc ← [1, NEW[BigCardinals.BigCARDRec[1]]];
bc.contents[0] ← Basics.LowHalf[lc];
}
ELSE {
bc ← [2, NEW[BigCardinals.BigCARDRec[2]]];
bc.contents[0] ← Basics.LowHalf[lc];
bc.contents[1] ← Basics.HighHalf[lc];
};
};
FirstOneBit:
PUBLIC PROC [bc: BigCard]
RETURNS [exp:
INT ← -1] = {
IF bc.size > 0
THEN {
temp: CARDINAL ← bc.contents[bc.size-1];
exp ← Basics.LongMult[bc.size-1, bitsPerWord];
DO
temp ← temp / 2;
IF temp = 0 THEN EXIT;
exp ← exp + 1;
ENDLOOP;
};
};