屏蔽C中参数给定的范围内的位

时间:2015-01-20 00:16:47

标签: c bit-manipulation bit-shift

我是C编程的新手,并不确定已经有一个很好的解释如何做到这一点,如果是这样,我很抱歉。我试图将位设置在给定的范围内。函数签名如下:

unsigned int setBits(int low, int high, unsigned int source) {

source是要操作的号码,low是该范围中的最低位,high是该范围中的最高位。当我试图特定地获得最后4位或前4位或其任何组合时,我理解位移很好,但是不理解如何从参数中将改变的范围中获得位。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:3)

如果是包容性的

mask = ~(~0 << (end - start + 1));
value = (n >> start) & mask;

其中n是原始整数,value是提取的位。

答案 1 :(得分:3)

2种方法:将source中的位从low设置为high的迭代方法:

unsigned int setBitsI(int low, int high, unsigned int source) {
  while (low <= high) {
    source |= 1u << low;
    low++;
  }
  return source;
}

非迭代方法:

unsigned int setBitsNI(int low, int high, unsigned int source) {
  unsigned setmask = 1u << (high - low);
  setmask <<= 1;
  setmask--;
  setmask <<= low;
  return source | setmask;
}

重要的是要避免1u << (1u + high - low)high为“bit-width-1”且low为0时1u << bit_widthlow为UB。

如果high或{{1}}的值超出位范围,则会出现问题。

答案 2 :(得分:0)

以下是一些移动和创建蒙版的简单示例,以激发更一般的表达。

1             == 00001b
1<<2          == 00100b
(1<<2)-1      == 00011b
((1<<2)-1)<<2 == 01100b

所以,

((1<<(high-low+1))-1)<<low

答案 3 :(得分:-1)

这是我的解决方案: 前面的if语句只包括有关低和高的条件。这通过了我给出的所有测试。

unsigned int setBits(int low, int high, unsigned int source)
 {
 if (low < 0)         {return source;}
 else if (high > 31)  {return source;}
 else if (low > high) {return source;}
 else {
         unsigned int mask = 0xFFFFFFFF << (31 - high);
         mask = mask >> ((31 - high) + low);
         mask = mask << low;
         return source | mask;
     }        

}