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

Set Bits C Code
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

Mask Bits
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