I need a fast bitcount for UInt64
My variables usually contain up to 8 bits set but regurlarly between 30 and 56.
At various places i found a fast one for UInt32 and on one site I even found a generalised version http://www.mathematik. uni-bielefeld.de/~sillke/PROBLEMS/bitcount (plus description).
The UInt32 version works fine but enhancing that by the line
w += w >> 32; simply doesn't work on my system (AMD-XP2700+ , windows XP). I don't know if this has something to do with 'wordorder' as I have a 32 bits system, or something else.
What I would like to know is how to extend that algorithm to get it working for UInt64 (using C#, Visual Studio Express 2008) or an alternative fast algorithm.
The code from that site:
******** Start code
int Count (unsigned int w)
{
// binary technique for 2**n bit words with n=5.
const unsigned int mask1h = (~0U) / 3 << 1;
const unsigned int mask2l = (~0U) / 5;
const unsigned int mask4l = (~0U) / 17;
// const unsigned int mask8l=(~0U)/(((1<<(128+8))-1)/255);
w -= (mask1h & w) >> 1;
w = (w & mask2l) + ((w>>2) & mask2l);
w += w >> 4; // 8 bit fold.
w &= mask4l; // set width=8.
w += w >> 8; // 16 bit fold.
w += w >> 16; // 32 bit fold.
// w += w >> 32; // 64 bit fold.
// w += w >> 64; // 128 bit fold.
// w &= mask8l; // set width=128.
// w += w >> 128; // 256 bit fold.
// w += w >> 256; // 512 bit fold.
// w += w >> 512; //1024 bit fold.
return w & 0xff; // select 8 bits. (4<=n<8)
// return w & 0xfffffffffffff fffffffffffffff ffff; //select 128 bits (n>=8)
}
*************** *** End code
(BTW I know about that improvement by AMD for UInt32 [making it faster indeed on my PC]
BitMask -= ((BitMask >> 1) & 0x55555555);
BitMask = (((BitMask >> 2) & 0x33333333) + (BitMask & 0x33333333));
BitMask = (((BitMask >> 4) + BitMask) & 0x0f0f0f0f);
return (ushort)((BitMa sk * 0x01010101) >> 24);
And it would be great if somebody could extend that for UInt64 s as well)
My variables usually contain up to 8 bits set but regurlarly between 30 and 56.
At various places i found a fast one for UInt32 and on one site I even found a generalised version http://www.mathematik. uni-bielefeld.de/~sillke/PROBLEMS/bitcount (plus description).
The UInt32 version works fine but enhancing that by the line
w += w >> 32; simply doesn't work on my system (AMD-XP2700+ , windows XP). I don't know if this has something to do with 'wordorder' as I have a 32 bits system, or something else.
What I would like to know is how to extend that algorithm to get it working for UInt64 (using C#, Visual Studio Express 2008) or an alternative fast algorithm.
The code from that site:
******** Start code
int Count (unsigned int w)
{
// binary technique for 2**n bit words with n=5.
const unsigned int mask1h = (~0U) / 3 << 1;
const unsigned int mask2l = (~0U) / 5;
const unsigned int mask4l = (~0U) / 17;
// const unsigned int mask8l=(~0U)/(((1<<(128+8))-1)/255);
w -= (mask1h & w) >> 1;
w = (w & mask2l) + ((w>>2) & mask2l);
w += w >> 4; // 8 bit fold.
w &= mask4l; // set width=8.
w += w >> 8; // 16 bit fold.
w += w >> 16; // 32 bit fold.
// w += w >> 32; // 64 bit fold.
// w += w >> 64; // 128 bit fold.
// w &= mask8l; // set width=128.
// w += w >> 128; // 256 bit fold.
// w += w >> 256; // 512 bit fold.
// w += w >> 512; //1024 bit fold.
return w & 0xff; // select 8 bits. (4<=n<8)
// return w & 0xfffffffffffff fffffffffffffff ffff; //select 128 bits (n>=8)
}
*************** *** End code
(BTW I know about that improvement by AMD for UInt32 [making it faster indeed on my PC]
BitMask -= ((BitMask >> 1) & 0x55555555);
BitMask = (((BitMask >> 2) & 0x33333333) + (BitMask & 0x33333333));
BitMask = (((BitMask >> 4) + BitMask) & 0x0f0f0f0f);
return (ushort)((BitMa sk * 0x01010101) >> 24);
And it would be great if somebody could extend that for UInt64 s as well)
Comment