我目前正在学习按位运算,我的任务是向左旋转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位还大。
任何帮助我了解此问题的帮助将不胜感激!
答案 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()的javascript实现,基于Answer中的上述Socowi (谢谢!)
我需要沿左(逆时针)和右(顺时针)方向模拟一个具有90度旋转角度的简单指南针(不是一个真正的指南针,只是一个有趣的问题。
因此,我没有想到通过存储先前的方向并使用* if / else *或* switch *来弄乱代码,而是想到了circular-shift或bit-rotation会带来更多的想法当然干净,高效和优雅。
但是,关于将掩码限制为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);
}