位循环移位

时间:2019-04-28 07:50:02

标签: java bitwise-operators bit

我目前正在学习按位运算,我的任务是向左旋转4位整数。

我向左旋转4位的代码是

private static int BITS_IN_INTEGER = 4;

private static int leftRotate(int x, int n) {
  return (x << n) | (x >> (BITS_IN_INTEGER - n));
}

我想进行4位循环移位以在旋转后保持为4位,但似乎无法理解其工作原理。

示例:向左旋转1位后有10(1010)会给我5(0101),但给我的值为21,比我的4位还大。

任何帮助我了解此问题的帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

如果我对你的理解正确,你想

  • 模拟BITS_IN_INTEGER位而不是32位的整数。
  • 对这样的模拟整数进行旋转

当前您可以进行旋转,但是实际int的高位(不属于仿真int的一部分)可以以0以外的值结尾。例如:

intput x
0000 0000  0000 0000  0000 0000  0000 1100
                                     |____|___, emulated int
result of rotating left by n=2       |    |
0000 0000  0000 0000  0000 0000  0011 0011

我们可以看到,我们要做的就是将模拟int上方的位(即32-BITS_IN_INTEGER高位)设置为零。为此,我们使用逻辑“和” &)。我们需要一个掩码,该掩码在我们要设置为零的位上带有0(任何& 0始终为0),在我们想要保留的位上带有1(所有{{1 }}永远是任何东西。

& 1

要使用 0...0 0011 0011 ← the result from before & 0...0 0000 1111 ← a mask —————————————————— 0...0 0000 0011 ← the masked result where unused bits are 0 0...01...1生成BITS_IN_INTEGER形式的掩码,我们可以使用1(1 << BITS_IN_INTEGER) - 1- 1转换为10000

01111

答案 1 :(得分:1)

这是 leftRotate() rightRotate()实现,基于Answer中的上述Socowi (谢谢!)

我需要沿左(逆时针)右(顺时针)方向模拟一个具有90度旋转角度的简单指南针(不是一个真正的指南针,只是一个有趣的问题。

因此,我没有想到通过存储先前的方向并使用* if / else *或* switch *来弄乱代码,而是想到了会带来更多的想法当然干净,高效和优雅。

但是,关于将掩码限制为4位,我遇到了同样的问题。由于上述解决方案,我得以做到! ;)

所以假设以下内容:

 - North = 1 = 0001
 - West  = 2 = 0010
 - South = 4 = 0100
 - East  = 8 = 1000

当我需要从北向西旋转90º时,我呼叫 leftRotate(),依此类推,直到再次到达同一点(北)。 / p>

反之亦然,如果从北转90º至->东,我叫 rightRotate(),然后再次转南,依此类推。 / p>

以下是代码段,希望对您有所帮助:

const BITS_IN_INTEGER = 4;
const INTEGER_MASK = (1 << BITS_IN_INTEGER) - 1;

// this function rotates to left (counter clockwise) 1,2,4,8...1,2,4,8

function leftRotate(x, n) {
  return INTEGER_MASK & ((x << n) | (x >>> (BITS_IN_INTEGER - n)));
}


// this function rotates to right (clockwise)  1,8,4,2...1,8,4,2

function rightRotate(x, n) {
  return INTEGER_MASK & ((x << (BITS_IN_INTEGER - n)) | (x >>> n));
}

// Lets rotate:

console.log('--- Rotate to left (counter clockwise) 1,2,4,8...1,2,4,8...1:')

let value = 1;

for (let i = 0; i < 8; i++) {
  console.log(value);
  value = leftRotate(value, 1);
}

console.log('-- Rotate to right (counter clockwise) 1,8,4,2...1,8,4,2...1:')

for (let i = 0; i < 8; i++) {
  console.log(value);
  value = rightRotate(value, 1);
}