3 #ifndef _GA_TBITARRAY_H
4 #define _GA_TBITARRAY_H
10 #include <limits.h> /* for CHAR_BIT */
12 #define CHAR_TBIT (CHAR_BIT>>1) // 8/2 = 4
14 #define TBITSHIFT(b) (((b) % CHAR_TBIT)<<1)
16 #define TBITMASK(b) /* Returns the bit mask of a byte */ \
19 #define TBITSLOT(b) ((b) / CHAR_TBIT) // Just the index of char[]
21 #define TBITGETVALUE(a, b) /* Get Value */ \
22 (((a)[TBITSLOT(b)] >> TBITSHIFT(b)) & 3)
23 // (((a)[2BITSLOT(b)] & 2BITMASK(b)) >> 2BITSHIFT(b))
25 #define TBITNSLOTS(nb) ((2*(nb) + CHAR_BIT - 1) / CHAR_BIT) // caltulate the length of char[]. x*2 can overflow while x<<1 cannot.
28 __inline void TBITSetValue ( char arr[], size_t index, uint_fast8_t value );
29 __inline uint_fast8_t TBITSaturatedADD ( char arr[], size_t index, int_fast8_t value );
30 __inline uint_fast8_t TBITSaturatedINC ( char arr[], size_t index );
31 __inline uint_fast8_t TBITSaturatedDEC ( char arr[], size_t index );
34 // I find gcc will not inline functions in other c files, thus move them here.
36 FORCE_INLINE
void TBITSetValue ( char arr
[], size_t index
, uint_fast8_t value
) {
38 unsigned char theByte
=(arr
[TBITSLOT(index
)]) & ~TBITMASK(index
);
39 theByte
|= value
<< TBITSHIFT(index
);
40 arr
[TBITSLOT(index
)] = theByte
;
43 FORCE_INLINE
uint_fast8_t TBITSaturatedADD ( char arr
[], size_t index
, int_fast8_t value
) {
44 unsigned char theByte
= (arr
[TBITSLOT(index
)]);
45 int_fast8_t theValue
= (theByte
>> TBITSHIFT(index
)) & 3 ;
47 return (uint_fast8_t) theValue
;
48 } else if (value
> 0) {
49 if (theValue
> 3-value
) theValue
=3;
50 else theValue
+= value
;
52 if (theValue
< -value
) theValue
=0;
53 else theValue
+= value
;
55 theByte
&= ~TBITMASK(index
);
56 theByte
|= theValue
<< TBITSHIFT(index
);
57 arr
[TBITSLOT(index
)] = theByte
;
58 return (uint_fast8_t) theValue
;
61 FORCE_INLINE
uint_fast8_t TBITSaturatedINC ( char arr
[], size_t index
) {
62 unsigned char theByte
= (arr
[TBITSLOT(index
)]);
63 uint_fast8_t theValue
= (theByte
>> TBITSHIFT(index
)) & 3 ;
68 theByte
&= ~TBITMASK(index
);
69 theByte
|= theValue
<< TBITSHIFT(index
);
70 arr
[TBITSLOT(index
)] = theByte
;
75 FORCE_INLINE
uint_fast8_t TBITSaturatedDEC ( char arr
[], size_t index
) {
76 unsigned char theByte
= (arr
[TBITSLOT(index
)]);
77 uint_fast8_t theValue
= (theByte
>> TBITSHIFT(index
)) & 3 ;
82 theByte
&= ~TBITMASK(index
);
83 theByte
|= theValue
<< TBITSHIFT(index
);
84 arr
[TBITSLOT(index
)] = theByte
;
91 #endif /* 2bitarray.h */
93 // Original comments for bitarray:
95 (If you don't have <limits.h>, try using 8 for CHAR_BIT.)
97 Here are some usage examples. To declare an ``array'' of 47 bits:
99 char bitarray[BITNSLOTS(47)];
103 BITSET(bitarray, 23);
105 To test the 35th bit:
107 if(BITTEST(bitarray, 35)) ...
109 To compute the union of two bit arrays and place it in a third array
110 (with all three arrays declared as above):
112 for(i = 0; i < BITNSLOTS(47); i++)
113 array3[i] = array1[i] | array2[i];
115 To compute the intersection, use & instead of |.
117 As a more realistic example, here is a quick implementation of the Sieve
118 of Eratosthenes, for computing prime numbers:
127 char bitarray[BITNSLOTS(MAX)];
130 memset(bitarray, 0, BITNSLOTS(MAX));
132 for(i = 2; i < MAX; i++) {
133 if(!BITTEST(bitarray, i)) {
135 for(j = i + i; j < MAX; j += i)