/* Library file: BitOps.Gl */ /* Created: 1st June 1996 by Felix */ /* */ /* Last modified: */ /* 18 Apr 97 FJR Removed code from OVecMWay.Gl */ /* */ /* Routines to allow for operations on single bits. Bit sets */ /* can have up to 32 elements. */ #DEFINECS MaxBit 32 /* Scaling factor */ BitScale = MakeHash(2, MaxBit); #DEFINECS EmptySet 0 /*** FN EmptySet = /* Routine to create an empty set */ /* Returns: empty set */ 0; /* ENDFN EmptySet */ ***/ PROC (1) = MakeHash (base, nPeriods); /* Form the constant vector needed to convert or restore */ /* dummies to/from an index */ /* pattern --> index: */ /* index = pattern*hashVec */ /* index --> pattern: */ /* pattern[i] = (index MOD modVec[i+1]) DIV modVec[i] */ /* Hash vector has lowest hash value on left */ /* In: */ /* base Base number */ /* nPeriods Number of periods in pattern */ /* Out: */ /* hashVec Hashing vector */ LOCAL i; LOCAL hashVec; hashVec = ZEROS (nPeriods, 1); i = 0; DO WHILE i < nPeriods; hashVec[i+1] = base^i; i = i + 1; ENDO; RETP (hashVec); ENDP; /* MakeHash */ PROC (1) = MkeScale(scale, numCols); /* Form the constant vectors needed for results scaling */ /* In: */ /* scale Scaling base for columns */ /* numCols Number of columns of info to store */ /* Out: */ /* scaleVec (MaxCols x 1) scale vector */ LOCAL i; LOCAL scaleVec; scaleVec = ZEROS (numCols, 1); i = 0; DO WHILE i < numCols; scaleVec[(numCols-i)] = scale^i; i = i + 1; ENDO; RETP (scaleVec); ENDP; /* MkeScale */ PROC (1) = SetBit (bitNo, currSet); /* Routine to set a bit in a set */ /* In: */ /* bitNo Number of bit to set */ /* currSet Current set of bits */ /* Out: */ /* currSet Set with bit bitNo set */ IF NOT TestBit(bitNo, currSet); currSet = currSet + BitScale[bitNo]; ENDIF; RETP (currSet); ENDP; /* SetBit */ PROC (1) = SetBits (bitNos, currSet); /* Routine to set several bits */ /* In: */ /* bitNo Vecotr of bits to set */ /* currSet Current set of bits */ /* Out: */ /* currSet Set with bit bitNo set */ LOCAL i; bitNos = UNIQUE(bitNos, 1); i = ROWS(bitNos); DO WHILE i > 0; currSet = SetBit(bitNos[i], currSet); i = i - 1; ENDO; RETP (currSet); ENDP; /* SetBit */ PROC (1) = ClearBit (bitNo, currSet); /* Routine to clear a bit in a set */ /* In: */ /* bitNo Number of bit to clear */ /* currSet Current set of bits */ /* Out: */ /* currSet Set with bit bitNo cleared */ IF TestBit(bitNo, currSet); currSet = currSet - BitScale[bitNo]; ENDIF; RETP (currSet); ENDP; /* ClearBit */ PROC (1) = ClearBts (bitNos, currSet); /* Routine to clear several bits */ /* In: */ /* bitNo Vector of bits to clear */ /* currSet Current set of bits */ /* Out: */ /* currSet Set with bit bitNo cleared */ LOCAL i; bitNos = UNIQUE(bitNos, 1); i = ROWS(bitNos); DO WHILE i > 0; currSet = ClearBit(bitNos[i], currSet); i = i - 1; ENDO; RETP (currSet); ENDP; /* ClearBts */ PROC (1) = TestBit (bitNo, currSet); /* Test whether a bit is set */ /* In: */ /* bitNo Number of bit to test */ /* currSet Current set of bits */ /* Out: */ /* bitIsSet True if bit bitNo is currently set */ /* NB we can use > and < rather than division because */ /* we know that this is a binary scale */ LOCAL bitIsSet; IF bitNo == MaxBit; bitIsSet = TRUNC(currSet / BitScale[MaxBit]); ELSE; bitIsSet = TRUNC((currSet % BitScale[bitNo+1])/BitScale[bitNo]); ENDIF; RETP (bitIsSet); ENDP; /* TestBit */ /* END BitOps.GL */