使用掩码来操纵一点麻烦

时间:2015-01-30 07:18:08

标签: c bit-manipulation mask

我正在处理一个函数,当x可以表示为n位,2的补码数时返回1,如果不能则表示0。现在我的代码适用于一些例子,如(5,3),( - 4,3)。但我不能让它适用于n大于x的情况(2,6)。有什么建议吗?谢谢。

我确实有限制,包括显式或隐式,相对比较运算符(<,>,< =和> =),除法,模数和乘法,减法,条件(如果或?:),循环,switch语句,函数调用和宏调用。假设1< n< 32。

int problem2(int x, int n){

    int temp = x;
    uint32_t mask;
    int maskco;

    mask = 0xFFFFFFFF << n;
    maskco = (mask | temp);

return (maskco) == x;

}

2 个答案:

答案 0 :(得分:1)

int problem2_mj(int x, int n){
    unsigned int r;
    int const mask = (-x) >> sizeof(int) * CHAR_BIT - 1;

    r = (-x + mask - (1 & mask)) ^ mask;  // Converts +n -> n, -n -> (n-1)
    return !(((1 << (n-1)) - r) >> sizeof(int) * CHAR_BIT - 1);
}
  1. 查找绝对值,如果数字为负数,则减去1
  2. 检查数字是否小于或等于2 n-1
  3. Check a working demo here


    根据您更新的请求,这里是代码如何添加两个数字:

    int AddNums(int x, int y)
    {
      int carry;
    
      // Iteration 1
      carry = x & y;  
      x = x ^ y; 
      y = carry << 1;
    
      // Iteration 2
      carry = x & y;  
      x = x ^ y; 
      y = carry << 1;
    
      ...
    
      // Iteration 31 (I am assuming the size of int is 32 bits)
      carry = x & y;  
      x = x ^ y; 
      y = carry << 1;
    
      return x;
    }
    

答案 1 :(得分:1)

在您的功能中,temp只是多余的,而maskco始终设置了最高位,因此如果x为正数,它将无效

简单的解决方案是掩盖最重要的位

int fit_in_n_bits(int x, int n)
{
    int maskabs = x >> sizeof(int) * CHAR_BIT - 1;
    int xabs    = (x + maskabs) ^ maskabs;  // xabs = |x|
    int nm      = ~n + 1U;                  // nm = -n
    int mask    = 0xFFFFFFFFU >> (32 + nm);
    return (xabs & mask) == xabs;
}

另一种方式:

int fit_in_n_bits(int x, int n)
{
    int nm       = ~n + 1U;
    int shift    = 32U + nm;
    int masksign = x >> (shift + 1);
    int maskzero = 0xFFFFFFFFU >> shift;
    return ((x & maskzero) | masksign) == x;
}

你也可以查看oon的方式here

int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
  int mask = x >> 31;

  return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}

One more way

/* 
 * fitsBits - return 1 if x can be represented as an 
 *  n-bit, two's complement integer.
 *   1 <= n <= 32
 *   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 2
 */
int fitsBits(int x, int n) {
    int r, c;
    c = 33 + ~n;
    r = !(((x << c)>>c)^x);
    return r;
}

相关: