Add function bitset_popcount

This commit is contained in:
Patrick Pelissier committed 2021-02-22 12:06:46 +01:00
1 parent 5fd6352a4e
commit 7b2e242c94
2 files changed
+41

No files matched your search

+30
View File
@@ -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) \
+11
View File
@@ -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)