在C中设置位

时间:2012-07-21 08:08:27

标签: c bit

我正在尝试执行以下操作:

  

编写一个函数setbits(x,p.n,y),返回x,其中n位开头   位置p设置为n的最右侧y位,而保留其他位   不变?

我试过这样但没有得到正确的答案。谁能告诉我哪里错了?

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    return (x>>p & (y|(~0<<n)));
}

4 个答案:

答案 0 :(得分:3)

类似的东西:

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    unsigned mask = (1U << n) - 1U; // n-bits
    y &= mask; // rightmost n bits of y
    y <<= p;   // which begin at position p
    mask <<= p; //idem
    x &= ~mask; //set the 0s
    x |= y;     //set the 1s
    return x;
}

或者如果你想用更少的线来做,更难调试,但是更酷:

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    unsigned mask = (1U << n) - 1U; // n-bits
    return (x & ~(mask << p)) | ((y & mask) << p);
}

答案 1 :(得分:1)

Kernighan和Ritchie,第2版,练习2-6。解决方案来自http://users.powernet.co.uk/eton/kandr2/krx206.html

(x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n))

答案 2 :(得分:1)

捕获y的最后n位:(将是最后n位等于y的数字,其他位设置为0)

last_n_bits_of_y = y & (((1<<(n+1))-1);

然后我们可以将它抵消(32-n-p + 1)(检查一下!)

last_n_bits_of_y_offset = last_n_bits_of_y << (32-n-p+1);

现在我们删除我们要更改的x位:

new_x = x & (~( (((1<<(n+1))-1) << (32-n-p+1) ) );

并用我们的位填充它:

new_x = new_x & last_n_bits_of_y_offset;

就是这样!没有真正测试它,但希望你能得到这个想法。

答案 3 :(得分:1)

  1. x>>()所以你松开了x最右边的位,然后再也不会在你的函数中恢复它们。
  2. 不能仅使用&设置位,因为结果取决于两个操作数,除非您知道其中一个只包含1
  3. (y|(~0<<n))应该从y剪切位,但不是,这次|不是正确的工具,使用&和适当的第二个操作数。
  4. 这是解决方案(我打赌有一个较短的解决方案,但这很简单):

    (x & ~(~(~0<<n)<<p) | (y&~(~0<<n)) << p);
    

    |的左侧部分清除x中的位置(位置p处的n位),右侧部分带来y位。