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;
|
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 */
|
/* Oplist for a bitset */
|
||||||
#define BITSET_OPLIST \
|
#define BITSET_OPLIST \
|
||||||
(INIT(bitset_init) \
|
(INIT(bitset_init) \
|
||||||
|
|||||||
@@ -366,6 +366,17 @@ static void test_clz(void)
|
|||||||
bitset_set_at(s1, 0, false);
|
bitset_set_at(s1, 0, false);
|
||||||
assert (bitset_clz(s1) == 64+620+1);
|
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)
|
int main(void)
|
||||||
|
|||||||
Reference in new issue
Block a user