Add function bitset_popcount
This commit is contained in:
1 parent
5fd6352a4e
commit
7b2e242c94
2 files changed
+41
No files matched your search
+30
@@ -786,6 +786,36 @@ bitset_clz(const bitset_t set)
|
||||
return s;
|
||||
}
|
||||
|
||||
// For GCC or CLANG or ICC
|
||||
#if defined(__GNUC__)
|
||||
static inline size_t m_b1tset_popcount64(bitset_limb_ct limb)
|
||||
{
|
||||
return (size_t) __builtin_popcountll(limb);
|
||||
}
|
||||
#else
|
||||
// MSVC __popcnt64 may not exist on the target architecture (no emulation layer)
|
||||
// Use emulation layer: https://en.wikipedia.org/wiki/Hamming_weight
|
||||
static inline size_t m_b1tset_popcount64(bitset_limb_ct limb)
|
||||
{
|
||||
limb = limb - ((limb >> 1) & 0x5555555555555555ULL);
|
||||
limb = (limb & 0x3333333333333333ULL) + ((limb >> 2) & 0x3333333333333333ULL);
|
||||
limb = (limb + (limb >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (limb * 0x0101010101010101ULL) >> 56;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Count the number of 1 */
|
||||
static inline size_t
|
||||
bitset_popcount(const bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT(set);
|
||||
size_t s = 0;
|
||||
size_t n = (set->size + M_B1TSET_LIMB_BIT - 1) / M_B1TSET_LIMB_BIT;
|
||||
for(size_t i = 0 ; i < n; i++)
|
||||
s += m_b1tset_popcount64(set->ptr[i]);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Oplist for a bitset */
|
||||
#define BITSET_OPLIST \
|
||||
(INIT(bitset_init) \
|
||||
|
||||
@@ -366,6 +366,17 @@ static void test_clz(void)
|
||||
bitset_set_at(s1, 0, false);
|
||||
assert (bitset_clz(s1) == 64+620+1);
|
||||
}
|
||||
|
||||
M_LET(s1, bitset_t) {
|
||||
bitset_set_str(s1, "[00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]");
|
||||
assert(bitset_popcount(s1) == 0);
|
||||
bitset_set_str(s1, "[10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]");
|
||||
assert(bitset_popcount(s1) == 1);
|
||||
bitset_set_str(s1, "[00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]");
|
||||
assert(bitset_popcount(s1) == 1);
|
||||
bitset_set_str(s1, "[10000011100000110010101010110000011111111111111110000001110001110001110001110000]");
|
||||
assert(bitset_popcount(s1) == 40);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
||||
Reference in new issue
Block a user