0

I'd like to ask how the BitMask looks like when I need to apply the hamming weight algoritm on an Int64 to count the set bits.

For an Int32 it looks like this:

    public int HammingWeight(int value)
  {
     value = value - ((value >> 1) & 0x55555555);
     value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
     return (((value + (value >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
  }

However since a Int32 is only 4 bytes long, a Int64 is 8 bytes long.

Therefore the same bitmask won't work on an Int64.

What is the correct Bitmask to use the hamming weight algorithm for an Int64 value?

EDIT : After checking the provided link from @just.ru I used this solution:

  /// <summary>
        /// Count the set bits in a ulong using 24 arithmetic operations (shift, add, and)..
        /// </summary>
        /// <param name="x">The ulong of which we like to count the set bits.</param>
        /// <returns>Amount of set bits.</returns>
        private static int HammingWeight(ulong x)
        {
            x = (x & 0x5555555555555555) + ((x >> 1) & 0x5555555555555555); //put count of each  2 bits into those  2 bits 
            x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); //put count of each  4 bits into those  4 bits 
            x = (x & 0x0f0f0f0f0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f0f0f0f0f); //put count of each  8 bits into those  8 bits 
            x = (x & 0x00ff00ff00ff00ff) + ((x >> 8) & 0x00ff00ff00ff00ff); //put count of each 16 bits into those 16 bits 
            x = (x & 0x0000ffff0000ffff) + ((x >> 16) & 0x0000ffff0000ffff); //put count of each 32 bits into those 32 bits 
            x = (x & 0x00000000ffffffff) + ((x >> 32) & 0x00000000ffffffff); //put count of each 64 bits into those 64 bits 
            return (int)x;
        }
yq8
  • 145
  • 1
  • 10
  • 1
    https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation – just.ru Aug 31 '16 at 15:13
  • 1
    The implementation is almost identical for 8-byte values. You just extend the constants, following the pattern already set. For the ones that are all 5s and 3s, it is obvious what to do. For `0x0F0F0F0F`, it becomes `0x0F0F0F0F0F0F0F0F`. Etc. See [here](https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel) for an even more general templated implementation. – Cody Gray - on strike Aug 31 '16 at 15:19

0 Answers0