4 ms·
Deliberately more obviously 'weird' version, from memory: uint64_t x = ...; for(size_t i = 1; i<UINT_BIT ;i*=2) // loop unroll { unsigned m = UINT_
by a1369209993 5y ago
Deliberately more obviously 'weird' version, from memory:
uint64_t x = ...;
for(size_t i = 1; i<UINT_BIT ;i*=2) // loop unroll
{
unsigned m = UINT_MAX / ((1<<i)+1); // constant-fold
// divide 2^(2k)-1 by 2^k+1 to get 2^k-1 in each group
// 2k-bit group means 2^k-1 sets bottom half
x = (x & m) + (x>>i & m);
// we can save a AND w/o carry but 1-bit and 2-bit
// need 2 ANDs to prevent carry between groups
// x = (x + (x>>i)) & m;
}