Occasionally, it is useful to be able to access individual binary digits of a number in order to read or change them. As an example of this we might mention the initialization of a CLINT object as a power of 2, which can be accomplished easily by setting a single bit.
In the following we shall develop three functions, setbit_l(), testbit_l(), and clearbit_l(), which set an individual bit, test a particular bit, and delete a single bit. The functions setbit_l() and clearbit_l() each return the state of the specified bit before the operation. The bit positions are counted from 0, and thus the specified positions can be understood as logarithms of powers of two: If n_l is equal to 0, then setbit_l(n_l, 0) returns the value 0, and afterwards, n_l has the value 20 = 1; after a call to setbit_l(n_l, 512), n_l has the value 2512 + 1.
Function: | test and set a bit in a CLINT object |
Syntax: | int setbit_l (CLINT a_l, unsigned int pos); |
Input: | a_l (CLINT argument) pos (bit position counted from 0) |
Output: | a_l (result) |
Return: | 1 if the bit at position pos was already set 0 if the bit at position pos was not set E_CLINT_OFL if overflow |
int setbit_l (CLINT a_l, unsigned int pos) { int res = 0; unsigned int i; USHORT shorts = (USHORT)(pos >> LDBITPERDGT); USHORT bitpos = (USHORT)(pos & (BITPERDGT - 1)); USHORT m = 1U << bitpos; if (pos > CLINTMAXBIT) { return E_CLINT_OFL; } if (shorts >= DIGITS_L (a_l)) {
If necessary, a_l is zero filled word by word, and the new length is stored in a_l[0].
for (i = DIGITS_L (a_l) + 1; i <= shorts + 1; i++) { a_l[i] = 0; } SETDIGITS_L (a_l, shorts + 1); }
The digit of a_l that contains the specified bit position is tested by means of the mask prepared in m, and then the bit position is set to 1 via an OR of the relevant digit with m. The function ends by returning the previous status.
if (a_l[shorts + 1] & m) { res = 1; } a_l[shorts + 1] |= m; return res; }
Function: | test a binary digit of a CLINT object |
Syntax: | int testbit_l (CLINT a_l, unsigned int pos); |
Input: | a_l (CLINT argument) pos (bit position counted from 0) |
Return: | 1 if bit at position pos is set 0 otherwise |
int testbit_l (CLINT a_l, unsigned int pos) { int res = 0; USHORT shorts = (USHORT)(pos >> LDBITPERDGT); USHORT bitpos = (USHORT)(pos & (BITPERDGT - 1)); if (shorts < DIGITS_L (a_l)) { if (a_l[shorts + 1] & (USHORT)(1U << bitpos)) res = 1; } return res; }
Function: | test and delete a bit in a CLINT object |
Syntax: | int clearbit_l (CLINT a_l, unsigned int pos); |
Input: | a_l (CLINT argument) pos (bit position counted from 0) |
Output: | a_l (result) |
Return: | 1 if bit at position pos was set before deletion 0 otherwise |
int clearbit_l (CLINT a_l, unsigned int pos) { int res = 0; USHORT shorts = (USHORT)(pos >> LDBITPERDGT); USHORT bitpos = (USHORT)(pos & (BITPERDGT - 1)); USHORT m = 1U << bitpos; if (shorts < DIGITS_L (a_l)) {
If a_l has enough digits, then the digit of a_l that contains the specified bit position is tested by means of the mask prepared in m, and then the bit position is set to 0 by an AND of the corresponding digit with the complement of m. The previous status of the bit position is returned at the termination of the function.
if (a_l[shorts + 1] & m) { res = 1; } a_l[shorts + 1] &= (USHORT)(~m); RMLDZRS_L (a_l); } return res; }
Team-Fly |