Lecture 09 Bit Sets
Joseph Haugh
University of New Mexico
Representing a Set
Consider the set of integers from 0 to 7
{0, 1, 2, 3, 4, 5, 6, 7}
How could we represent this set in C?
How could we represent subsets of this set?
How could we perform set operations?
Using Bits for a Set
- Each bit of an integer can be used considered a separate boolean value
- Let the bit in position
n
represent whether or or not n
is in the set
- Example Set:
{1, 3, 6, 7}
- Binary:
11001010
- Example Set:
{5}
- Binary:
00100000
- Singleton sets can be simply created by shifting, can we combine them?
Set Operations
A = {1, 3, 6, 7} |
11001010 |
a = 0xCA; |
B = {0, 1, 4, 6} |
01010011 |
b = 0x53; |
A ∪ B |
11011011 |
uAB = a | b; |
A ∩ B |
01000010 |
iAB = a & b; |
Counting Bits
- How could we count the number of items are in a set?
- Basically how many bits are set to 1?
Counting by Looping
int numBitsSet(short n) {
int i;
int count = 0;
for(i = 0; i < 16; i++) {
if(n & (1 << i)) count++;
}
return count;
}
How could you do this without a loop?
Counting with Shifting and Masking
int numBitsSet(short n) {
int value = n;
value = (value & 0x5555) +
((value >> 1) & 0x5555);
value = (value & 0x3333) +
((value >> 2) & 0x3333);
value = (value & 0x0f0f) +
((value >> 4) & 0x0f0f);
value = (value & 0x00ff) +
((value >> 8) & 0x00ff);
return value;
}
Counting with Shifting and Masking
0x5555 |
0101 0101 0101 0101 |
0x3333 |
0011 0011 0011 0011 |
0x0f0f |
0000 1111 0000 1111 |
0x00ff |
0000 0000 1111 1111 |
Counting with Shifting and Masking
Let’s try it with n = 0xF1A2
which is 1111 0001 1010 0010
which has 8 bits set
value =
(value & 0x5555)
+
((value >> 1) & 0x5555);
value |
= |
1111 0001 1010 0010 |
0x5555 |
= |
0101 0101 0101 0101 |
& |
|
0101 0001 0000 0000 |
Counting with Shifting and Masking
value =
(value & 0x5555)
+
((value >> 1) & 0x5555);
value |
= |
1111 0001 1010 0010 |
>> 1 |
|
0111 1000 1101 0001 |
0x5555 |
= |
0101 0101 0101 0101 |
& |
|
0101 0000 0101 0001 |
Counting with Shifting and Masking
value =
(value & 0x5555)
+
((value >> 1) & 0x5555);
(value & 0x5555) |
= |
0101 0001 0000 0000 |
((value >> 1) & 0x5555) |
= |
0101 0000 0101 0001 |
+ |
|
1010 0001 0101 0001 |
Counting with Shifting and Masking
value =
(value & 0x3333)
+
((value >> 2) & 0x3333);
value |
= |
1010 0001 0101 0001 |
0x3333 |
= |
0011 0011 0011 0011 |
& |
|
0010 0001 0001 0001 |
Counting with Shifting and Masking
value =
(value & 0x3333)
+
((value >> 2) & 0x3333);
value |
= |
1010 0001 0101 0001 |
>> 2 |
|
0010 1000 0101 0100 |
0x3333 |
= |
0011 0011 0011 0011 |
& |
|
0010 0000 0001 0000 |
Counting with Shifting and Masking
value =
(value & 0x3333)
+
((value >> 2) & 0x3333);
(value & 0x3333) |
= |
0010 0001 0001 0001 |
((value >> 2) & 0x3333) |
= |
0010 0000 0001 0000 |
+ |
|
0100 0001 0010 0001 |
Counting with Shifting and Masking
value =
(value & 0x0f0f)
+
((value >> 4) & 0x0f0f);
value |
= |
0100 0001 0010 0001 |
0x0f0f |
= |
0000 1111 0000 1111 |
& |
|
0000 0001 0000 0001 |
Counting with Shifting and Masking
value =
(value & 0x0f0f)
+
((value >> 4) & 0x0f0f);
value |
= |
0100 0001 0010 0001 |
>> 4 |
|
0000 0100 0001 0010 |
0x0f0f |
= |
0000 1111 0000 1111 |
& |
|
0000 0100 0000 0010 |
Counting with Shifting and Masking
value =
(value & 0x0f0f)
+
((value >> 4) & 0x0f0f);
(value & 0x0f0f) |
= |
0000 0001 0000 0001 |
((value >> 4) & 0x0f0f) |
= |
0000 0100 0000 0010 |
+ |
|
0000 0101 0000 0011 |
Counting with Shifting and Masking
value =
(value & 0x00ff)
+
((value >> 8) & 0x00ff);
value |
= |
0000 0101 0000 0011 |
0x00ff |
= |
0000 0000 1111 1111 |
& |
|
0000 0000 0000 0011 |
Counting with Shifting and Masking
value =
(value & 0x00ff)
+
((value >> 8) & 0x00ff);
value |
= |
0000 0101 0000 0011 |
>> 8 |
|
0000 0000 0000 0101 |
0x00ff |
= |
0000 0000 1111 1111 |
& |
|
0000 0000 0000 0101 |
Counting with Shifting and Masking
value =
(value & 0x00ff)
+
((value >> 8) & 0x00ff);
(value & 0x00ff) |
= |
0000 0000 0000 0011 |
((value >> 8) & 0x00ff) |
= |
0000 0000 0000 0101 |
+ |
|
0000 0000 0000 1000 |