有点列移位

时间:2010-07-06 18:51:09

标签: c++ bit-manipulation

如何在8x8区域中移动列?例如,我有一个64位无符号整数,如下所示:

#include <boost/cstdint.hpp>

int main()
{
    /** In binary:
      * 
      * 10000000
      * 10000000
      * 10000000
      * 10000000
      * 00000010
      * 00000010
      * 00000010
      * 00000010
      */
    boost::uint64_t b = 0x8080808002020202;
}

现在,我想把第一个垂直行换成四次,之后就变成了这个:

/** In binary:
  * 
  * 00000000
  * 00000000
  * 00000000
  * 00000000
  * 10000010
  * 10000010
  * 10000010
  * 10000010
  */

  b == 0x82828282;

这可以通过逐位运算符相对快速地完成,还是什么?

5 个答案:

答案 0 :(得分:5)

我最好的猜测是:

(((b & 0x8080808080808080) >> 4 * 8) | (b & ~0x8080808080808080)

我们的想法是隔离列位并仅移位它们。

答案 1 :(得分:2)

  

这可以通过逐位运算符相对快速地完成,还是什么?

您如何做到这取决于您想要制定解决方案的“通用”方式。总是第一列?总是换班4?

这是一个想法:

  • 前4个字节代表前4行。利用它,遍历前4名。
  • 使用0x8屏蔽第一列,以查看该位是否已设置。
  • 将该位移位4个字节(>>4),当然它需要在uint64内才能完成。
  • biwise-或(|)它反对新字节。

通过避免循环和编写更多代码,你可能会做得更好。

答案 2 :(得分:1)

可能有SIMD指令。您必须在VC ++设置中打开这些指令,当然它们不适用于AMD / Intel处理器以外的架构。

答案 3 :(得分:0)

答案 4 :(得分:0)

完全猜测,因为我没有编译器或Boost库可用:

给定b,col(从右边开始计数1到8)和移位(移位距离) 在您的示例中,col为8,shift为4。

boost::uint64_t flags = 0x0101010101010101;
boost::uint64_t mask  = flags << (col -1);
boost::int64_t eraser = -1 ^ flags;
boost::uint64_t data = b & mask;
data = data >> (8*shift)
b = (b & eraser) | data;