uint128: Implement popcount()

This commit is contained in:
theoreticalbts 2015-07-13 15:56:04 -04:00
parent 0391665471
commit 5f43c06bae
2 changed files with 29 additions and 1 deletions

View file

@ -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;

View file

@ -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()); }