8

I had a problem in hand as this : "Exercise 2-6. Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged."

I've written a function for this as below. This is working as expected.

int func_setx(int x,int p,int n,int y)
{
    int a_t= ~0 << (p+n);
    int b_t= ~a_t >> n;
    int x_t= x& (a_t | b_t);    // a temporary x which has the bits to be changed as 0 , rest of the bits unchanged.

    int mask= (y << p) & (~(~0 << (p+n)));     // a mask which has required bits from y in positions to be set , rest all bits 0.

    printf("\nCheckpoint : mask= %x  x_t= %x\n",mask,x_t);

    int result= mask|x_t;
    return result;
}

But I somehow feel the logic is long and can be optimized, but can't think of any other way yet. Can anyone suggest any optimization to this please?

Diwakar Sharma
  • 415
  • 1
  • 9
  • 26
  • 1
    You'll probably find an answer at [Bit Twiddling Hacks](http://graphics.stanford.edu/~seander/bithacks.html) — and you should bookmark the page even if you don't find the answer there. – Jonathan Leffler Jun 27 '13 at 05:14
  • Numerous duplicates, e.g. [k&r exercise confusion with bit-operations](http://stackoverflow.com/questions/2076084/kr-exercise-confusion-with-bit-operations) and [returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving other bits unchanged](http://stackoverflow.com/questions/6727351/returns-x-with-the-n-bits-that-begin-at-position-p-set-to-the-rightmost-n-bits-o) and [Setting Bits in C](http://stackoverflow.com/questions/11590545/setting-bits-in-c) – Paul R Jun 27 '13 at 08:32

1 Answers1

10

To make an n bit mask:

mask_y = (1U << n) - 1;

To start it at bit p:

mask_x = mask_y << p;

Clear the appropriate bits in x:

x &= ~mask_x;

Extract the bits from y:

y &= mask_y;

Upshift them to position p:

y <<= p;

Put it all together:

result = x | y;

Or in a more compact form:

mask = (1U << n) - 1;
result = x & ~(mask << p);
result |= (y & mask) << p; 
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • 1
    Assuming 32-bit integers, if `n == 32`, this solution causes undefined behaviour. That case is just `return y`, though, so it's easy to special-case. Alternately, use `1ULL` (or however you want to get a 64-bit type) instead of `1U`. – Carl Norum Jun 27 '13 at 04:43
  • +1 for not just giving the code but also explaining what it does step-by-step – legends2k Jun 27 '13 at 04:58
  • Carl, your comment should properly be part of your answer. – Jim Balter Jun 27 '13 at 05:33
  • It's more of an aside than part of the answer, really, which is why I left it a comment. NBD. – Carl Norum Jun 27 '13 at 16:50