我在网上搜索了从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
这不是我想要的答案,所以我做错了什么?
答案 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 1st
和4th
位置(LSB到MSB),输出应为11
表示3
。
首先找到no of ones
b / w这些2
位置,这个旋转循环从starting position
到ending 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
。
答案 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