如何编写Bits的“轮子”

时间:2015-07-07 13:03:50

标签: c++

我想用一定长度的Bits编程一个“wheel”,并且只有一个Bit设置为“true”。一旦我旋转轮子(90°),这个位也必须旋转。

像长度:= 4:

    1             0             0             0             1
  0   0   ==>   0   1   ==>   0   0   ==>   1   0   ==>   0   0
    0             0             1             0             0

OR

    0001 ==> 0010 ==> 0100 ==> 1000 ==> 0001

轮子完全旋转后,必须调用其他功能。

对此进行编码的好方法是什么?

3 个答案:

答案 0 :(得分:1)

此操作称为位旋转。

unsigned rotate_left(unsigned x, unsigned num_bits, int delta) {
    unsigned rdelta = delta % num_bits;
    unsigned mask = (1 << num_bits) - 1;
    return ((x << rdelta) | (x >> (num_bits - rdelta))) & mask;
}

这将旋转包含x位的num_bits位的位轮delta。负迁移也应该有效。通过将rotate_right更改为<<可以获得等效的>>函数,反之亦然。

如果num_bits为32并且您需要此操作以非常快的速度执行,则可以使用内在函数来执行机器旋转指令。

附录:测试最右边(第零)位,当然使用:

if (x & 1) { ...

测试位N:

if (x & (1 << N)) { ...

如果您需要超过32位,请使用unsigned longunsigned long long(取决于您的平台)。如果您需要任意数量的位,此解决方案无法正常工作 - 您需要使用基于某些位的内容,例如在std::bitset上,如第二个答案,或vector<bool>

答案 1 :(得分:0)

你的&#34;轮&#34;可以表示为内存中的位域。 如果所需长度小于64,则可以使用任何整数类型来实现它。很简单:

void shift_clockwise(unsigned long long *wheel, int size) {
    unsigned long long first_bit = (*wheel) & 1ll;
    (*wheel) = ((*wheel) >> 1) & (first_bit << (size-1));        
}

如果尺寸较大,则可以使用std::bitset,例如:

void shift_clockwise(std::bitset<wheel_size>& wheel) {
    bool first_bit = wheel.test(0);
    wheel >>= 1;
    set(wheel.size()-1, first_bit);
}

答案 2 :(得分:0)

由于您知道只有一个1位,因此存储所有0&#39}毫无意义。只需存储1的位置。

struct Wheel {
    Wheel(int size)
    : _size(size)
    , _onePos(0) {}

    void rotate() {
        ++_onePos;
        if(_onePos == _size) {
            _onePos = 0;
            onFullRotation();
        }
    }

    unsigned int bits() const {
        return 1u << _onePos;
    }

private:
    void onFullRotation() {
        std::cout << "<full rotation>";
    }

    int const _size;
    int _onePos;
};

Live on Coliru