可以,使用Hamming Weight wikipedia article中描述的方法。
由于 sqlite 在最有效的实现中会将相乘的值上转换为 REAL,因此我们必须使用仅加法和移位实现。
//types and constants used in the functions below
//uint64_t is an unsigned 64-bit integer variable type (defined in C99 version of C language)
const uint64_t m1 = 0x5555555555555555; //binary: 0101...
const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
...
//This uses fewer arithmetic operations than any other known
//implementation on machines with slow multiplication.
//This algorithm uses 17 arithmetic operations.
int popcount64b(uint64_t x)
{
x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
x += x >> 8; //put count of each 16 bits into their lowest 8 bits
x += x >> 16; //put count of each 32 bits into their lowest 8 bits
x += x >> 32; //put count of each 64 bits into their lowest 8 bits
return x & 0x7f;
}
在 SQLlite 中实现,如下所示:
SELECT a, b, (x + (x >> 32)) & 0x7f AS Distance FROM (
SELECT a, b, x + (x >> 16) AS x FROM (
SELECT a, b, x + (x >> 8) AS x FROM (
SELECT a, b, (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f AS x FROM (
SELECT a, b, (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333) AS x FROM (
SELECT a, b, x - ((x >> 1) & 0x5555555555555555) AS x FROM (
-- In my case, I'm counting the bits from an x-or.
SELECT a, b, (~(a&b))&(a|b) AS x FROM (
...
)
))))))