减少操作次数

时间:2014-03-04 23:23:42

标签: c bit-manipulation

我有一个函数来切换每个十六进制数字的第0和第3位,但它使用26个操作。我只想将它减少到1到25次操作。只使用按位运算! 〜& ^ | +<< >>

int swap30(int x) {
    int m = 0b10001000 << 24;
    int m1 = 0b10001000 << 16;
    int m2 = 0b10001000 << 8;
    int m3 = 0b10001000;
    int mask1 = m | m1 | m2 | m3;

    int z = 0b01100110 << 24;
    int z1 = 0b01100110 << 16;
    int z2 = 0b01100110 << 8;
    int z3 = 0b01100110;
    int mask2 = z | z1 | z2 | z3;

    int y = 0b00010001 << 24;
    int y1 = 0b00010001 << 16;
    int y2 = 0b00010001 << 8;
    int y3 = 0b00010001;
    int mask3 = y | y1 | y2 | y3;

    int three = x & mask1;
    int stable = x & mask2;
    int one = x & mask3;
    int final2 = ((three >> 3) & mask3) | stable | (one << 3);
    return final2;
}

2 个答案:

答案 0 :(得分:3)

return (x & 0x66666666) | ((x >> 3) & 0x11111111) | ((x & 0x11111111) << 3);

答案 1 :(得分:0)

  1. 将低位移至高位并屏蔽掉结果位。
  2. 将高位移至低位并屏蔽掉结果位。
  3. 屏蔽掉所有尚未移动的位。
  4. 将结果与OR结合使用。
  5. 代码:

    unsigned SwitchBits(unsigned n) {
      return ((n << 3) & 0x88888888) | ((n >> 3) & 0x11111111) | (n & 0x66666666);
    }
    

    另外,如果你想要非常聪明。它可以通过两个较少的操作完成,但由于一些指令之间的依赖性,这实际上可能不会更快。

    1. 移动高位以与低位对齐
    2. 如果高位和低位相同,则在低位中记录0,如果它们不同则为1
    3. 由此,只屏蔽每个半字节的低位。
    4. 由此,乘以9,这将保持低位,并将其复制到高位。
    5. 由此,XOR与原始值。在高位和低位相同的情况下,不会发生正确的变化。如果它们不同,它们将被有效地交换。
    6. 代码:

      unsigned SwitchBits(unsigned n) {
        return ((((n >> 3) ^ n) & 0x11111111) * 0x9) ^ n;
      }