如何return中间位?

How to return middle bits?

我在网上搜索了一下 returning x bits from start 的常见解决方案似乎是:

mask = ((1 << x) - 1 ) << start

然后,mask & value.

但是,我仍然对它的工作原理感到困惑。

如果我有一个数字 0101 1100 并且我想 return 来自位置 5 和 6 的两位 (11)

mask = ((1<<2)-1) << 5

1<<2 = 0000 0100,减去 1 得到 0000 0011 然后,移动 5 是 0110 0000

如果我取 0110 0000 & 0101 1100(原来的),我得到 0100 0000

这不是我想要的答案,我做错了什么?

位的位置通常从最低到最高有效计数,即从右到左。

0101 1110
---- ----
7654 3210

您想要的位是位 2 和位 3。

假设我们指的是二进制补码,那么 11 将是位 2 和 3(或 3 和 4,具体取决于您问的是谁)。

这样想。如果要从二进制值的中间获取特定数量的位,则可以先将其向右移动 n 次,其中 n 是感兴趣的第一个位的索引。

向右移动 0101 1100 两次得到 0001 0111

在这里,我们对前两位感兴趣,所以我们可以简单地调用 0001 0111 & 3 因为 3 = 00000011.

因此,此特定示例的公式为 (b >> 2) & 3,其中 b 是二进制值。

如果你想要他们当前位置的值,你可以调用 0101 1100 & 12 因为 12 = 00001100,returns 0000 1100.

例如输入数字是 92 = 0101 1100 初始位置 = 1 结束位置 = 4

现在你的任务是找到数字b/w 1st4th的位置(LSB to MSB),输出应该是11意味着3 .

首先找到no of ones b/w这些2位置,对于这个从starting positionending position的旋转循环,然后做

sum = sum | 1<<i; // sum =12( 1100)

接下来,如果你这样做 sum & num,你将得到输出 b/w 给定的位置,这是 1100 但你需要 11 所以 1100 >> 2(which is n1+1)

这是我的解决方案

   int sum = 0,num,res; /** num is your input number **/
   for(int i=n1+1;i<n2;i++) /* n1 is starting position and n2 is the ending position */
            sum = sum | (1<<i); //counting ones
    res = sum & num; // we will get o/p in middle 
    res = res>>(n1+1); // shift previous res to correct position

最后打印 res

正如许多人所建议的,您应该从右侧开始定位。

   num =   0101 1100
Positions: 8765 4321

那么给定的解决方案就可以了。


然而,我自己更详细的方法是:

要获取位置 3 和 4 ('11') 的位值,我将执行以下操作:

假设您想要位置 k 的钻头。将 a 1, k-1 位置向左移动并使用 &- 运算符对其进行评估。将它移回去,然后将结果保存在一个数组中,数组的长度是你想要的位数。对其余部分重复此过程。

int mask = 1 << (k - 1);
int bitAtPosK = (num & mask) >> (k - 1);

...循环执行此操作并保存结果。

位置 3 的可视化:

num = 0101 1100
1 << 2 results in 0000 0010

and
0101 1100
0000 0100
--------- &
0000 0100

0000 0100 >> 2 results in 1