按位比较

时间:2014-08-25 17:53:28

标签: c bit-manipulation

我有一个表示8x8“bit”块的数组

unsigned char plane[8]

我想要做的是水平循环这个“位”块 并计算发生变化的次数 10

当我提取一点时,它被存储在一个 unsigned char,所以基本上我想增加一个计数 当一个char非零而另一个为零时。

我所拥有的是以下内容:

int getComplexity(unsigned char *plane) {
    int x, y, count = 0;
    unsigned char bit;

    for(x = 0; x < 8; x++) {
        for(y = 0; y < 8; y++) {
            if(y == 0) {
                bit = plane[x] & 1 << y;
                continue;
            }

        /*
        MISSING CODE
        */
        }
    }
}

对于丢失的代码,我可以这样做:

if( (bit && !(plane[x] & 1 << y)) || (!bit && (plane[x] & 1 << y)) ) {
    bit = plane[x] & 1 << y;
    count++;
}

然而,我真正想要的是,如果有的话 巧妙的按位操作来代替这一步 有两个单独的测试。

1 个答案:

答案 0 :(得分:2)

这实际上只是一个gcc解决方案,因为popcnt内在函数不能用于每个其他编译器。

unsigned char plane[8];

static const uint64_t tmask = 0x8080808080808080UL;

uint64_t uplane = *(uint64_t *)plane; // pull the whole array into a single uint

return __builtin_popcnt( ~tmask & (uplane ^ (uplane >> 1) ) );

对于x86,popcnt指令实际上没有实现,直到sse4.2(所以最近)。 此外,尽管看起来它依赖于字节序,但它并不是因为掩码所允许的单个字节都不允许交互。 它对内存的工作方式做了一些假设:\

作为旁注在&#34;水平&#34;中做同样的事情。方向也很简单:

return __builtin_popcnt(0xFFFFFFFFFFFFFFUL & ( uplane ^ (uplane >> 8) ) );