如何返回中间位?

时间:2018-01-27 17:42:25

标签: c bit-manipulation bit bit-shift

我在网上搜索了从x返回start位的常见解决方案似乎是:

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

然后,mask & value

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

如果我有一个数字0101 1100,我想从第5和第6位返回两位(11

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

1<<2 = 0000 0100,减去1会产生0000 0011然后,转移5为0110 0000

如果我选择0110 0000 & 0101 1100(原文),我会0100 0000

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

4 个答案:

答案 0 :(得分:3)

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

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

0101 1100向右移动两次会产生0001 0111

在这里,我们对前两位感兴趣,因此我们只需致电0001 0111 & 3,因为3 = 00000011

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

如果您想要当前位置的值,可以致电0101 1100 & 12,因为12 = 00001100会返回0000 1100

答案 1 :(得分:1)

比特位置通常从最小到最重要,即从右到左计数。

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

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

答案 2 :(得分:0)

例如输入num是92 = 0101 1100         初始pos = 1         结束pos = 4

现在您的任务是查找数字b / w 1st4th位置(LSB到MSB),输出应为11表示3

首先找到no of ones b / w这些2位置,这个旋转循环从starting positionending position并执行

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

接下来,如果您执行sum & num,您将获得输出b / w给定的位置为1100,但您需要111100 >> 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

答案 3 :(得分:0)

正如许多人所建议的那样,你应该从右边开始定位。

   num =   0101 1100
Positions: 8765 4321

然后给定的解决方案工作正常。

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

要获取位置3和4(&#39; 11&#39;)的位值,我会执行以下操作:

让我们说你想要位置k的位。将1,k-1位置向左移动并使用&amp; -operator进行评估。将其移回,然后将结果保存在一个数组中,其长度为您想要的位数。其余的重复这个过程。

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