user1413523
user1413523

Reputation: 345

Setting Bits in C

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

Upvotes: 5

Views: 1401

Answers (4)

M&#225;rcio Paiva
M&#225;rcio Paiva

Reputation: 1003

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.

Upvotes: 1

rodrigo
rodrigo

Reputation: 98348

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

Upvotes: 3

nshy
nshy

Reputation: 1074

  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.

Upvotes: 1

Oleg2718281828
Oleg2718281828

Reputation: 1039

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))

Upvotes: 1

Related Questions