Setting Bits in C

血红的双手。 提交于 2019-12-06 03:29:30

问题


I'm trying to do the following:

Write a func setbits(x,p.n,y) that returns x with n bits that begin at position p set to the rightmost n bits of y,leaving the other bits unchanged?

I tried it like this but not getting correct answers. Can anyone tell where I am wrong?

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

回答1:


Something like:

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;
}

Or if you want to do it in fewer lines, more difficult to debug, but waaaay cooler:

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



回答2:


Kernighan and Ritchie, 2nd edition, exercise 2-6. The solution is from http://users.powernet.co.uk/eton/kandr2/krx206.html :

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




回答3:


  1. You x>>() so you loose x rightmost bits and then never restore them later in you function.
  2. One can not set bits using only & because the result depends on both operands unless you know one of them consists only of 1
  3. (y|(~0<<n)) is supposed to cut bits from y but it's not, this time | is not the right tool, use & and appropriate second operand.

Here is the solution(I bet there is shorter one, but this is straight-forward):

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

Left part of | clears the place in x(n bits at position p) and the right part brings y bits.




回答4:


Catching the last n bits of y: (will be a number with the last n bits equal to y, and the others set to zero)

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

then we can offset it by (32-n-p+1) (check this!)

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

now we erase the bits of x we want to change:

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

and populate it with our bits:

new_x = new_x & last_n_bits_of_y_offset;

That's it! Didn't really test it, but hopefully, you'll get the idea.



来源:https://stackoverflow.com/questions/11590545/setting-bits-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!