jack06215

[tools] count number of bit

Jul 8th, 2020 (edited)
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. #ifndef __bitcount__
  2. #define __bitcount__
  3.  
  4. #include <iostream>
  5.  
  6.  
  7. class BitCount
  8. {
  9. public:
  10.     /*
  11.     * Iterative bit counting. O(b) where b number of bits (int = 32) (long = 64)
  12.     */
  13.     static int countU(unsigned int  n)
  14.     {
  15.         int count = 0;
  16.         while (n)
  17.         {
  18.             count += (int)(n & 0x1u);
  19.             n >>= 1;
  20.         }
  21.         return count;
  22.     }
  23.  
  24.     static int countL(unsigned long n)
  25.     {
  26.         int count = 0;
  27.         while (n)
  28.         {
  29.             count += (int)(n & 0x1l);
  30.             n >>= 1;
  31.         }
  32.         return count;
  33.     }
  34.  
  35.     /*
  36.     * Sparse ones. O(b1) where b1 is the number of 1's bit.
  37.     * Sparse Ones and Dense Ones were first described by Peter Wegner in
  38.     *"A Technique for Counting Ones in a Binary Computer",
  39.     * Communications of the ACM, Volume 3 (1960) Number 5, page 322.
  40.     */
  41.     static int countSOL(unsigned int n)
  42.     {
  43.         int count = 0;
  44.         for (count = 0; n; ++count)
  45.             n &= (n - 1);
  46.         return count;
  47.     }
  48.     static int countSOL(unsigned long n)
  49.     {
  50.         int count = 0;
  51.         while (n)
  52.         {
  53.             count++;
  54.             n &= (n - 1);
  55.         }
  56.         return count;
  57.     }
  58.  
  59.     static int countDOL(unsigned int n)
  60.     {
  61.         int count = 8 * sizeof(unsigned int);
  62.         n ^= (unsigned int)-1;
  63.         while (n)
  64.         {
  65.             count--;
  66.             n &= (n - 1);
  67.         }
  68.         return count;
  69.     }
  70.     static int countDOL(unsigned long n)
  71.     {
  72.         int count = 8 * sizeof(unsigned long);
  73.         n ^= (unsigned long)-1;
  74.         while (n)
  75.         {
  76.             count--;
  77.             n &= (n - 1);
  78.         }
  79.         return count;
  80.     }
  81.  
  82.     /*
  83.     * Pre computed look up table for 8bits and 16bits.
  84.     * O(C) constant but space is compromised. for 8bits is 256 bytes of memory.
  85.     * and for 16 bits is 64KB of
  86.     */
  87.     static const char bits_in_char[256];
  88.     static const char bits_in_char16[0x1u << 16];
  89.  
  90.     static int countPRE8U(unsigned int n)
  91.     {
  92.         return  bits_in_char[n & 0xffu] +
  93.             bits_in_char[(n >> 8) & 0xffu] +
  94.             bits_in_char[(n >> 16) & 0xffu] +
  95.             bits_in_char[(n >> 24) & 0xffu];
  96.     }
  97.     static int countPRE8L(unsigned long n)
  98.     {
  99.         return  bits_in_char[n & 0xffl] +
  100.             bits_in_char[(n >> 8) & 0xffl] +
  101.             bits_in_char[(n >> 16) & 0xffl] +
  102.             bits_in_char[(n >> 24) & 0xffl] +
  103.             bits_in_char[(n >> 32) & 0xffl] +
  104.             bits_in_char[(n >> 40) & 0xffl] +
  105.             bits_in_char[(n >> 48) & 0xffl] +
  106.             bits_in_char[(n >> 56) & 0xffl];
  107.     }
  108.  
  109.     static int countPRE16U(unsigned int n)
  110.     {
  111.         return  bits_in_char16[n & 0xffffu] +
  112.             bits_in_char16[(n >> 16) & 0xffffu];
  113.     }
  114.     static int countPRE16L(unsigned long n)
  115.     {
  116.         return  bits_in_char16[n & 0xffffl] +
  117.             bits_in_char16[(n >> 16) & 0xffffl] +
  118.             bits_in_char16[(n >> 32) & 0xffffl] +
  119.             bits_in_char16[(n >> 48) & 0xffffl];
  120.     }
  121.  
  122.  
  123.     /*
  124.     * Parallel Bit Counting. Counting the number of bits every each pair of bits. Then 4bits, 8bits,
  125.     * 16bits.... O(C) constant and space is reduced from look up tables.
  126.     */
  127.  
  128.     //01010101 01010101 01010101 01010101   (unsigned long)(-1)/3     2^(2^0) + 1
  129. #define MASK_55555555 (((unsigned int)(-1))/3)
  130.     //00110011 00110011 00110011 00110011   (unsigned long)(-1)/5     2^(2^1) + 1
  131. #define MASK_33333333 (((unsigned int)(-1))/5)
  132.     //00001111 00001111 00001111 00001111   (unsigned long)(-1)/17    2^(2^2) + 1
  133. #define MASK_0F0F0F0F (((unsigned int)(-1))/17)
  134.     //11111111 00000000 11111111 00000000   (unsigned long)(-1)/257   2^(2^3) + 1
  135. #define MASK_00FF00FF (((unsigned int)(-1))/257)
  136.     //00000000 00000000 11111111 11111111   (unsigned long)(-1)/65537 2^(2^4) + 1
  137. #define MASK_0000FFFF (((unsigned int)(-1))/65537)
  138.  
  139.     //01010101 01010101 01010101 01010101
  140. #define MASKL_55555555 (((unsigned long)(-1))/3)
  141.     //00110011 00110011 00110011 00110011
  142. #define MASKL_33333333 (((unsigned long)(-1))/5)
  143.     //00001111 00001111 00001111 00001111
  144. #define MASKL_0F0F0F0F (((unsigned long)(-1))/17)
  145.     //11111111 00000000 11111111 00000000
  146. #define MASKL_00FF00FF (((unsigned long)(-1))/257)
  147.     //00000000 00000000 11111111 11111111
  148. #define MASKL_0000FFFF (((unsigned long)(-1))/65537)
  149.     //11111111 11111111 11111111 11111111
  150. #define MASKL_FFFFFFFF ((unsigned long)(-1))
  151.  
  152.     static int countParallelU(unsigned int n)
  153.     {
  154.         //for (int i = 0; i < 5; ++i)
  155.         //  n = (n & mask[i]) + (( n >> shift[i]) & mask[i]);
  156.         n = (n & MASK_55555555) + ((n >> 1) & MASK_55555555);
  157.         n = (n & MASK_33333333) + ((n >> 2) & MASK_33333333);
  158.         n = (n & MASK_0F0F0F0F) + ((n >> 4) & MASK_0F0F0F0F);
  159.         n = (n & MASK_00FF00FF) + ((n >> 8) & MASK_00FF00FF);
  160.         n = (n & MASK_0000FFFF) + ((n >> 16)& MASK_0000FFFF);
  161.         return n;
  162.     }
  163.     static int countParallelL(unsigned long n)
  164.     {
  165.         //for (int i = 0; i < 6; ++i)
  166.         //  n = (n & maskL[i]) + (( n >> shift[i]) & maskL[i]);
  167.         n = (n & MASKL_55555555) + ((n >> 1) & MASKL_55555555);
  168.         n = (n & MASKL_33333333) + ((n >> 2) & MASKL_33333333);
  169.         n = (n & MASKL_0F0F0F0F) + ((n >> 4) & MASKL_0F0F0F0F);
  170.         n = (n & MASKL_00FF00FF) + ((n >> 8) & MASKL_00FF00FF);
  171.         n = (n & MASKL_0000FFFF) + ((n >> 16)& MASKL_0000FFFF);
  172.         n = (n & MASKL_FFFFFFFF) + ((n >> 32)& MASKL_FFFFFFFF);
  173.         return (int)n;
  174.     }
  175.  
  176.     /*
  177.     * Nifty Parallel.
  178.     * According to Don Knuth (The Art of Computer Programming Vol IV, p 11), in the first textbook on
  179.     * programming, The Preparation of Programs for an Electronic Digital Computer by Wilkes, Wheeler and
  180.     * Gill (1957, reprinted 1984), pages 191--193 presented Nifty Parallel Count by D B Gillies and J C P
  181.     * Miller.
  182.     */
  183.     static int countNiftyU(unsigned int n)
  184.     {
  185.         n = (n & MASK_55555555) + ((n >> 1) & MASK_55555555);
  186.         n = (n & MASK_33333333) + ((n >> 2) & MASK_33333333);
  187.         n = (n & MASK_0F0F0F0F) + ((n >> 4) & MASK_0F0F0F0F);
  188.         return n % 255;
  189.     }
  190.  
  191.  
  192.     static int countNiftyL(unsigned long n)
  193.     {
  194.         n = (n & MASKL_55555555) + ((n >> 1) & MASKL_55555555);
  195.         n = (n & MASKL_33333333) + ((n >> 2) & MASKL_33333333);
  196.         n = (n & MASKL_0F0F0F0F) + ((n >> 4) & MASKL_0F0F0F0F);
  197.         return (int)(n % 255);
  198.     }
  199.  
  200.     /*
  201.     *  MIT HAKMEN -only works for 32 bits-
  202.     */
  203.     static int countHAKMEMU(unsigned int n)
  204.     {
  205.         unsigned int tmp;
  206.         tmp = n - ((n >> 1) & 033333333333)
  207.             - ((n >> 2) & 011111111111);
  208.         return ((tmp + (tmp >> 3)) & 030707070707) % 63;
  209.     }
  210.  
  211. };
  212.  
  213. #endif
Add Comment
Please, Sign In to add comment