2

我正在做这个编程项目,其中一部分是编写一个只使用位运算符的函数,每两位切换一次。我想出了一种梳状算法来实现这一点,但它只适用于无符号数,有什么想法可以让它也适用于有符号数吗?我完全被这个难住了。继承人我到目前为止:

        // Mask 1 - For odd bits
    int a1 = 0xAA; a1 <<= 24;
    int a2 = 0xAA; a2 <<= 16;
    int a3 = 0xAA; a3 <<= 8;
    int a4 = 0xAA;
    int mask1 = a1 | a2 | a3 | a4;

    // Mask 2 - For even bits
    int b1 = 0x55; b1 <<= 24;
    int b2 = 0x55; b2 <<= 16;
    int b3 = 0x55; b3 <<= 8;
    int b4 = 0x55;
    int mask2 = b1 | b2 | b3 | b4;

    // Mask Results
    int odd = x & mask1;
    int even = x & mask2;

    int newNum = (odd >> 1) | (even << 1);

    return newNum;

通过将变量或变量组合在一起手动创建掩码是因为唯一可以使用的常量在 0x00-0xFF 之间。

4

4 回答 4

3

问题是odd >> 1它将用负数扩展符号。只需再做一次and即可消除重复的位。

int newNum = ((odd >> 1) & mask2) | (even << 1);
于 2013-09-18T19:05:48.450 回答
2

最小化运算符并注意符号扩展问题给出:

int odd = 0x55;
odd |= odd << 8;
odd |= odd << 16;

int newnum =   ((x & odd) << 1 )  // This is (sort of well defined)
             | ((x >> 1) & odd);  // this handles the sign extension without
                                  // additional & -operations

不过要注意一点:位旋转通常只应用于无符号整数。

于 2013-09-18T19:28:43.163 回答
0

当您右移一个有符号的数字时,该符号也将被扩展。这称为符号扩展。通常,当您处理位移时,您希望使用无符号数。

于 2013-09-18T19:08:46.973 回答
0

通过一次处理一个字节来最小化常量的使用:

unsigned char* byte_p;
unsigned char byte;
int ii;
byte_p = &x;   
for(ii=0; ii<4; ii++) {
  byte = *byte_p;
  *byte_p = ((byte & 0xAA)>>1) | ((byte & 0x55) << 1);
  byte_p++;
}     

最小化操作并保持 和 之间0x00的常数0xFF

unsigned int comb = (0xAA << 8) + 0xAA;
comb += comb<<16;
newNum = ((x & comb) >> 1) | ((x & (comb >> 1)) << 1);

10 次操作。

刚刚看到上面的评论并意识到这正在实施(或多或少)@akisuihkonen 提出的一些建议。所以认为这是帽子的一角!

于 2013-09-18T19:08:56.580 回答