uint128: Implement popcount()
This commit is contained in:
parent
0391665471
commit
5f43c06bae
2 changed files with 29 additions and 1 deletions
|
|
@ -108,6 +108,8 @@ namespace fc
|
|||
|
||||
static void full_product( const uint128& a, const uint128& b, uint128& result_hi, uint128& result_lo );
|
||||
|
||||
uint8_t popcount() const;
|
||||
|
||||
// fields must be public for serialization
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
|
|
|
|||
|
|
@ -325,7 +325,33 @@ namespace fc
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t _popcount_64( uint64_t x )
|
||||
{
|
||||
static const uint64_t m[] = {
|
||||
0x5555555555555555ULL,
|
||||
0x3333333333333333ULL,
|
||||
0x0F0F0F0F0F0F0F0FULL,
|
||||
0x00FF00FF00FF00FFULL,
|
||||
0x0000FFFF0000FFFFULL,
|
||||
0x00000000FFFFFFFFULL
|
||||
};
|
||||
// TODO future optimization: replace slow, portable version
|
||||
// with fast, non-portable __builtin_popcountll intrinsic
|
||||
// (when available)
|
||||
|
||||
for( int i=0, w=1; i<6; i++, w+=w )
|
||||
{
|
||||
x = (x & m[i]) + ((x >> w) & m[i]);
|
||||
}
|
||||
return uint8_t(x);
|
||||
}
|
||||
|
||||
uint8_t uint128::popcount()const
|
||||
{
|
||||
return _popcount_64( lo ) + _popcount_64( hi );
|
||||
}
|
||||
|
||||
void to_variant( const uint128& var, variant& vo ) { vo = std::string(var); }
|
||||
void from_variant( const variant& var, uint128& vo ){ vo = uint128(var.as_string()); }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue