Advertisement
runnig

Bit counting, array convolution to uint64_t

Sep 22nd, 2012
417
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.05 KB | None | 0 0
  1. // Denis Gorodetskiy, [email protected]
  2.  
  3. // Given an array A with elements A[i] from range [0..63]
  4. // for instance, A = {1, 2, 5},
  5. // we convolute their elements to a single uint64_t variable V = {0,1,1,0,0,1}
  6. // with bits set at positions pointed by array elements A[i]
  7.  
  8. #include <assert.h>
  9. #include <stdint.h>
  10.  
  11. using namespace std;
  12.  
  13. // sets a bit of integer v at position bitpos
  14. void setbit(uint64_t & v, int bitpos)
  15. {
  16.     assert(bitpos >= 0 && bitpos < 64);
  17.     uint64_t mask = 0x1;
  18.     mask <<= bitpos;
  19.     v |= mask;
  20. }
  21.  
  22. template < typename T >
  23. uint64_t value_bits(T & arr, size_t length)
  24. {
  25.     uint64_t ret = 0;
  26.     for(int i = 0; i < length; ++i)
  27.     {
  28.         setbit(ret, arr[i]);
  29.     }
  30.     return ret;
  31. }
  32.  
  33. static const int8_t bittable[] = {
  34. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  35. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  36. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  37. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  38. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  39. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  40. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  41. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
  42. };
  43.  
  44. template < typename T >
  45. int bitcount(T v)
  46. {      
  47.     // use __popcnt(v) intrinsic instead of this function if your cpu supports it.
  48.  
  49.     int bits = 0;
  50.  
  51.     for(int i = 0; i < sizeof(T); ++i)
  52.     {
  53.         uint8_t ch = v & 0xFF;
  54.         v >>= 8;
  55.         bits += bittable[ch];
  56.     }
  57.     return bits;
  58. }
  59.  
  60. int main(int argc, char * argv[])
  61. {
  62.     int arr1[] =  {0, 1, 2, 3, 10, 11, 23};
  63.     int arr2[] = {1, 2, 3, 4, 23};
  64.  
  65.     uint64_t v1 = value_bits(arr1, 7);
  66.     uint64_t v2 = value_bits(arr2, 5);
  67.  
  68.     int num_common_elements = bitcount(v1 & v2);
  69.  
  70.     assert(num_common_elements == 4);
  71.  
  72.     return 0;
  73. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement