左循环位移位

Left circular bit shift

我必须编写一个函数来对 y 位置的位进行左循环移位。 例如,如果我输入:010110002作为 y,函数必须 return 01100001.

我试过Integer.rotateLeft(),但似乎没用。

我认为这应该可行:

int rotate_8bits_left(int val, int y) {
    // amend y to the range [0, 7] with this:
    // y = ((y % 8) + 8) % 8;
    // or better, with this:
    y = y & 0x7;
    // do the rotation
    return ((val << y) & 0xFF) | (val >> (8-y));
}

让我们解释一下不同的部分:

// move val left y bits:
(val << y)

但是上面保留了超过第 8 位的位,所以我们需要截断它们,所以我们选择:

// move val left y bits and truncate anything beyond the 8th bit:
(val << y) & 0xFF

现在我们需要将输出的位添加到开头。我们只要向右移动就可以算出向左出去的位:

// move to the right, 8-y bits
val >> (8-y)

如果我们现在将两个部分粘合在一起,我们将得到旋转:

int new_val = ((val << y) & 0xFF) | (val >> (8-y));

现在对于第一部分,我们要处理可能不在 [0, 8] 范围内的 y。我们可以修改 y 到这个范围,在使用它之前,用:

y = ((y % 8) + 8) % 8;

上面的表达式固定了 y 的负值和正值,如果 y 是负数,模数将 return 是 [-7, -1] 范围内的负值,然后通过加 8 我们得到到正值范围。我们必须再次进行取模,对于 y 为正的情况,加上 8 来修复负的情况,使其回到 8 以上。第二个取模解决了这个问题。

但是我们可以通过更简单的方法对 y 进行相同的修改,只保留 [0, 7] 范围内遇到的前 3 位,将 8 视为 0,这可以通过以下方式完成表达式,它适用于 y 的负值和正值:

y = y & 0x7;